Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataTemplate for an array or IEnumerable

I would like to create an implicit DataTemplate that works on an array or IEnumerable of my class. This way I have a template that describes how to render a bunch of items instead of just one. I want to do this so I can, among other things, show the results in a tooltip. eg

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

The tooltip should see that Invoices is a bunch of items and use the appropriate data template. The template would look something like this:

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

That didn't work so I tried the example from this post x:Type and arrays--how? which involves creating a custom markup extension. This works if you specify the key but not for an implicit template

So then I tried making my own custom markup extension inheriting from TypeExtension like below but I get an error that says "A key for a dictionary cannot be of type 'System.Windows.Controls.StackPanel'. Only String, TypeExtension, and StaticExtension are supported." This is a really weird error as it is taking the content of the datatemplate as the key?? If I specify a key then it works fine but that largely defeats the purpose.

[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();
    }
}
like image 428
MikeKulls Avatar asked Sep 10 '25 23:09

MikeKulls


1 Answers

As noted in the question you linked to {x:Type ns:TypeName[]} works. It may screw over the designer but at runtime it should be fine.

To avoid designer errors the template can be moved to App.xaml or a resource dictionary (or of course just don't use the designer at all).

(The error mentioning the control inside the template sounds like a bug in the code generator or compiler, sadly i doubt that there is much you can do about that one.)

like image 199
H.B. Avatar answered Sep 13 '25 11:09

H.B.