1

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?

Community
  • 1
  • 1
psubsee2003
  • 8,563
  • 8
  • 61
  • 79
  • in the thread you linked to there is an example of xaml for a dictionary. any reason why you cannot use that implementation? I might be misinterpreting what it is you are trying to do. – default Jan 18 '15 at 10:02
  • @Default I am using it, but I need to define a `HierarchicalDataTemplate` for the KeyValuePairs within that dictionary as the Value object has another collection that will be another leaf in the `TreeView`. So I need to be able to define the structure below it. I tried hooking to the `Values` property, which does work, but because the `Values` collection is not observable, any changes to the Dictionary do not get shown in the `TreeView` – psubsee2003 Jan 18 '15 at 11:29
  • In your `HierarchicalDataTemplate` you are binding `MyList` to `ItemsSource`. But the `KeyValuePair` hasn't the `MyList` property. Could `MyClass` be the source of the template? – Il Vic Jan 18 '15 at 21:49
  • @IlVic should be Value.MyList. A typo when creating my example. – psubsee2003 Jan 18 '15 at 21:53

1 Answers1

1

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.

Community
  • 1
  • 1
Il Vic
  • 5,576
  • 4
  • 26
  • 37