2016-11-08 60 views
0

我在我的XAML是這樣的:WPF的TreeView不拿起模板,調用toString()方法,而不是

<TreeView DataContext="{Binding Source={StaticResource Locator}}" ItemsSource="{Binding SomeTree.TopLevelItems}"> 
    <TreeView.Resources> 
     <DataTemplate DataType="{x:Type vm:ILeaf}"> 
      <CheckBox Content="{Binding Name}" IsThreeState="False" IsChecked="{Binding IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
     </DataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type vm:IGroup}" ItemsSource="{Binding Children}"> 
      <CheckBox Content="{Binding Name}" IsThreeState="True" IsChecked="{Binding IsEnabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 

vm:相應地定義:

xmlns:vm="clr-namespace:My.ViewModels.MyTree" 

而且MyTree命名空間包含接口IGroupILeaf

SomeTree.TopLevelItems是可枚舉的IGroup s和ILeaf s(它是動態填充的)。

現在,我的TreeView應該相應地顯示一個複選框樹,但它只顯示項目源的頂級元素,不應用數據模板,而是在元素上調用ToString()

The other post which mentions the same problem這裏不適用,我已經檢查過了。

我在想什麼/做錯了什麼?

+2

如果我沒有記錯的話,你不能使用DataTemplates for Interfaces(多個可能適用)。可能的解決方法在這裏:[如何將DataTemplate數據類型綁定到接口?](http://stackoverflow.com/questions/15023441/how-to-bind-datatemplate-datatype-to-interface)可選解決方案:實現您自己的['DataTemplateSelector '](https://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector(v = vs.110).aspx) –

+0

我改變了這一點,並把正確的類放在{x :鍵入}但它沒有改變任何東西。或者視圖模型中的列表還必須是非接口類型的? – rabejens

+2

正如@ManfredRadlwimmer發現的那樣,你不能使用數據類型的接口(只是想想問題:如果給定的對象實現兩者,應該選擇哪一個?)。請參閱[this](https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e774a24-0deb-4acd-a719-32abd847041d/data-templates-and-interfaces?forum=wpf)相關主題disccussion。典型的解決方案是使用模板選擇器。 – Sinatr

回答

1

模板只工作過具體的類沒有接口,

這是一個功能,如果你有1類2個接口,它應該選擇哪個模板?

因爲系統無法知道那麼你不能做到這一點

看到這裏充滿MS響應https://social.msdn.microsoft.com/Forums/vstudio/en-US/1e774a24-0deb-4acd-a719-32abd847041d/data-templates-and-interfaces?forum=wpf

改用DataTemplateSelector,而不是類型查找,這樣就可以告訴系統如何解釋多接口的情況

public class TaskListDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate 
     SelectTemplate(object item, DependencyObject container) 
    { 
     FrameworkElement element = container as FrameworkElement; 

     if (element != null && item != null && item is Task) 
     { 
      Task taskitem = item as Task; 

      if (taskitem.Priority == 1) 
       return 
        element.FindResource("importantTaskTemplate") as DataTemplate; 
      else 
       return 
        element.FindResource("myTaskTemplate") as DataTemplate; 
     } 

     return null; 
    } 
}