2012-02-24 2 views
2

Я хотел бы создать неявный DataTemplate, который работает с массивом или IEnumerable моего класса. Таким образом, у меня есть шаблон, который описывает, как отображать кучу элементов, а не только один. Я хочу сделать это, чтобы я мог, среди прочего, показать результаты в всплывающей подсказке. напримерDataTemplate для массива или IEnumerable

<TextBlock Text="{Binding Path=CustomerName}" ToolTip="{Binding Path=Invoices}"> 

В подсказке должно быть указано, что Счета-фактуры представляют собой набор элементов и используют соответствующий шаблон данных. Шаблон будет выглядеть примерно так:

<DataTemplate DataType="{x:Type Customer[]}"> 
    <ListBox "ItemsSource={Binding}"> 
    etc 

Это не сработало, так что я попробовал пример с этого поста x:Type and arrays--how?, который включает в себя создание нестандартного модуля разметки. Это работает, если вы укажете ключ, но не для неявного шаблона

Итак, я попытался создать собственное собственное расширение разметки, наследующее от TypeExtension, как показано ниже, но я получаю сообщение об ошибке «Ключ для словаря не может быть типа» System.Windows.Controls.StackPanel '. Поддерживаются только String, TypeExtension и StaticExtension. " Это действительно странная ошибка, так как она принимает содержимое таблицы данных как ключ? Если я укажу ключ, тогда он отлично работает, но в значительной степени побеждает цель.

[MarkupExtensionReturnType(typeof(Type)), TypeForwardedFrom("PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] 
public class ArrayTypeExtension 
    : TypeExtension 
{ 
    public ArrayTypeExtension() : base() { } 

    public ArrayTypeExtension(Type type) : base(type) 
    { 
    } 

    public ArrayTypeExtension(string value) : base(value) 
    { 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     Type val = base.ProvideValue(serviceProvider) as Type; 
     return val == null ? null : val.MakeArrayType(); 
    } 
} 
+0

Разве вы не можете просто создать шаблон данных для одного объекта, а затем привязать список в 'ListBox'? – annonymously

+0

Это не очень хорошо ... –

+0

Это правда, но в некоторых случаях это предпочтительнее. В моем случае я представляю данные в DataGrid, поэтому вы не можете указать шаблон для каждого элемента, вам нужен шаблон для каждого столбца. В других случаях было бы просто иметь возможность сделать это. – MikeKulls

ответ

3

Как отмечалось в этом вопросе вы связаны с {x:Type ns:TypeName[]}работ. Это может завинтить конструктора, но во время работы все должно быть хорошо.

Чтобы избежать ошибок дизайнера, шаблон можно перенести в App.xaml или словарь ресурсов (или, конечно же, совсем не использовать конструктор).

(Ошибка упоминая управления внутри шаблона звучит как ошибка в генераторе кода или компилятор, к сожалению, я сомневаюсь, что есть много вы можете сделать о том.)

+0

Привет, HB, спасибо за ответ. Я не понимал, что это просто ошибка дизайнера. Несмотря на то, что он работает, я все еще не думаю, что это хорошее решение для появления ошибок в подобной сборке. В основном эта ошибка - это то, что я пытаюсь устранить. Я попробовал собственное расширение разметки, но это было бесполезно. Кстати, у меня были xmlns в моем коде, я просто не поставил его на вопрос, когда я набрал его вручную. Рассмотрим его Псевдокод. :-) – MikeKulls

+1

@MikeKulls: Мне нужно будет не согласиться на проблему с ошибкой, они абсолютно искусственны, это не проблема в сборке, это просто визуальный студийный дизайнер, являющийся куском хлама. Я никогда бы не заметил таких «ошибок», потому что я не использую конструктор и, следовательно, они вообще не возникают *. Ошибка, упоминающая элемент управления внутри шаблона, звучит как ошибка в генераторе кода или компиляторе, к сожалению, я сомневаюсь, что вы можете многое сделать с этим. –

+0

Боюсь, нам придется не согласиться на этот вопрос. :-) Я понимаю, что дизайнер - это кусок хлама, и я сам не использую его сам, но для этого есть использование.Однако я нашел обходное решение, которое пока что дает лучшее из обоих миров и на самом деле то, что я хотел в любом случае. Вы просто переместите DataTemplate в App.xaml или словарь ресурсов. У дизайнера нет никаких ошибок. Можете ли вы добавить это как отредактировать свой ответ для будущих поколений программистов? – MikeKulls

2

Если вы ОК с созданием вашего собственный тип, я просто пробовал и следил, и он работает. Создание определенного типа для вашей коллекции:

public class InvoiceCollection : List<Invoice> { } 

public class Customer { 
    public string name { get; set; } 
    InvoiceCollection invoices { get; set; } 
} 

и затем XAML с шаблоном данных:

<DataTemplate DataType={x:Type InvoiceCollection}> 
    <ListBox ItemsSource="{Binding}" /> 
</DataTemplate> 

<TextBox Text="{Binding name}" Tooltip="{Binding invoices}" /> 
+1

Я бы подумал, что это тоже хорошие варианты. Преимущество заключается в том, что он, по-видимому, является более стабильным вариантом в VS2010 с небольшим недостатком немного большего набора текста. – MikeKulls

Смежные вопросы