psubsee2003
psubsee2003

Reputation: 8741

Defining a DataTemplate for a KeyValuePair

I am attempting to specify a KeyValuePair<int,MyClass> as the data type for a DataTemplate in WPF. The KeyValuePair is from an ObservableDictionary object (I am using Dr WPF's implementation if it is relevant.

Using How to reference a generic type in the DataType attribute of a HierarchicalDataTemplate?, I was able to get something close, however, I am getting a compiler error.

I need to be able to define the HierarchicalDataTemplate for the KeyValuePair so I can create another leaf in the TreeView below it containing a collection that is part of the Value object of the Dictionary.

The XAML is simply:

<HierarchicalDataTemplate DataType="{local:GenericKeyValuePairType  
                                     KeyType=sys:Int32, 
                                     ValueType=local:MyClass}" 
                          ItemsSource="{Binding Path=Value.MyList}" />

And GenericKeyValuePairType is a MarkupExtension

public class GenericKeyValuePairType : MarkupExtension
{
    public Type KeyType { get; set; }
    public Type ValueType { get; set; }


    public GenericKeyValuePairType() { }
    public GenericKeyValuePairType(Type keyType, Type valueType)
    {
        KeyType = keyType;
        ValueType = valueType;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return typeof(KeyValuePair<,>).MakeGenericType(this.KeyType, this.ValueType);
    }
}

When I do this, Visual Studio indicates that this is not valid. The specific error is:

A key for a dictionary cannot be of type 'TreeViewBindingTest.GenericKeyValuePairType'. Only String, TypeExtension, and StaticExtension are supported.

Is what I am trying to do even possible? If so, is there a better approach?

Upvotes: 1

Views: 3703

Answers (1)

Il Vic
Il Vic

Reputation: 5666

In my opinion using KeyValuePair as DataContext of a TreeViewItem is not correct. KeyValuePair is sealed, so you can't implement the INotifyPropertyChanged interface. Moreover you can't use your GenericKeyValuePairType extension since the compiler believe that you want to use that object as DataType (read here for more info).

Indeed your model is MyClass object (you confirmed that MyList property belongs to it). In this case your DataTemplate will be:

<HierarchicalDataTemplate DataType="{x:Type local:MyClass}" 
                          ItemsSource="{Binding Path=MyList}" />

I believe it is conceptually more correct.

Upvotes: 2

Related Questions