2012-12-10 89 views
0

我是新來的WPF,所以可能會丟失一些明顯的東西,但一直無法找到答案。泛型類不綁定到HierarchicalDataTemplate

基本上我正在構建一個自定義樹集合,它以特定的方式進行排序,樹的節點被鍵入到集合的類型。當在TreeView中進行測試時,HierarchicalDataTemplate在節點通用時不起作用。如果他們不是通用的,那很好。

下面是一個簡單的節點類來說明:

public class SimpleNode<T> 
{ 
    private List<SimpleNode<T>> _children; 
    private string _name; 

    public SimpleNode(string name) 
    { 
     _name = name; 
    } 

    public List<SimpleNode<T>> Children 
    { 
     get 
     { 
      return _children; 
     } 
     set 
     { 
      _children = value; 
     } 
    } 

    public string Name 
    { 
     get 
     { 
      return _name; 
     } 
    } 
} 

然後在XAML:

HierarchicalDataTemplate DataType="{x:Type local:SimpleNode`1}" ItemsSource="{Binding Children}" 

顯然附加到類型的'1是具有1個通用PARAM SimpleNode的結果。如果我刪除類的泛型HierarchicalDataTemplate工程,我可以在TreeView查看樹。隨着泛型的到位,它不會這樣做。

任何想法?

在此先感謝。

回答

2

開箱即用並不支持。但是,你可以把它通過創建自己的DataTemplateSelector支持泛型工作:

public class OpenGenericTypeDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, 
               DependencyObject container) 
    { 
     var element = container as FrameworkElement; 
     if (item != null && element != null) 
     { 
      if (item.GetType().IsGenericType) 
      { 
       var genericTypeDefinition = item.GetType() 
               .GetGenericTypeDefinition(); 
       var key = new DataTemplateKey(genericTypeDefinition); 
       return element.TryFindResource(key) as DataTemplate; 
      } 
     } 

     return null; 
    } 
} 

你不是可以這樣使用它:

<UserControl.Resources> 
    <OpenGenericTypeDataTemplateSelector x:Key="GenericTemplateSelector" /> 
</UserControl.Resources> 
... 
<TreeView ItemTemplateSelector="{StaticResource GenericTemplateSelector}" ...> 
    <TreeView.Resources> 
    <HierarchicalDataTemplate DataType="{x:Type local:SimpleNode`1}" 
           ItemsSource="{Binding Children}"> 
     ... 
    </HierarchicalDataTemplate> 
    </TreeView.Resources> 

那是什麼呢,其實很簡單:
當您創建一個DataTemplate對於某種類型,該類型的名稱將自動成爲該模板的關鍵。
默認DataTemplateSelector使用該項目的類型作爲查找值。但是泛型類的實例的類型是封閉泛型類型,即具有指定泛型類型參數的類型。
問題是:模板已註冊爲開放式泛型類型,即沒有指定泛型類型參數。這就是爲什麼默認DataTemplateSelector沒有選擇DataTemplate註冊爲開放式泛型類型。
我提供的實現通過簡單地檢查項目的類型來添加對開放泛型類型的支持。如果它是通用的,我們將自己定義爲開放的泛型類型(通過GetGenericTypeDefinition)並將其用作關鍵字。

要真正使用這個選擇器,我們必須告訴TreeView它應該使用它。我們通過指定ItemTemplateSelector來做到這一點。

+0

非常感謝,我會仔細檢查一下,看看我能不能弄清楚你在這裏做了什麼。另外對於一個快速解決方案,我發現另一篇文章建議製作一個非泛型基類,並在WPF中引用它 - 這似乎也起作用。 [鏈接] http://stackoverflow.com/questions/6586528/datatemplates-and-generic-types – user1373164

+0

@ user1373164:我添加了一個解釋發生在這裏。一個非泛型的基類是可以工作的,但它只是標準的'DataTemplateSelector'實現的一個短暫的解決方法,因此我不會推薦它。 –

+0

再次感謝 - 我會試試看。 – user1373164