WPF HiercharchicalDataTemplate.DataType: How to react on interfaces?

霸气de小男生 提交于 2019-12-30 10:43:12

问题


Problem

I've got a collection of IThings and I'd like to create a HierarchicalDataTemplate for a TreeView. The straightforward DataType={x:Type local:IThing} of course doesn't work, probably because the WPF creators didn't want to handle the possible ambiguities.

Since this should handle IThings from different sources at the same time, referencing the implementing class is out of question.

Current solution

For now I'm using a ViewModel which proxies IThing through a concrete implementation:

public interface IThing {
    string SomeString { get; }
    ObservableCollection<IThing> SomeThings { get; }
    // many more stuff
}

public class IThingViewModel
{
     public IThing Thing { get; }
     public IThingViewModel(IThing it) { this.Thing = it; }
}

<!-- is never applied -->
<HierarchicalDataTemplate DataType="{x:Type local:IThing}">

<!-- is applied, but looks strange -->
<HierarchicalDataTemplate
    DataType="{x:Type local:IThingViewModel}"
    ItemsSource="{Binding Thing.SomeThings}">
    <TextBox Text="{Binding Thing.SomeString}"/>
</HierarchicalDataTemplate>

Question

Is there a better (i.e. no proxy) way?


回答1:


The reason for this is that the default template selector supports only concrete types, not interfaces. You need to create a custom DataTemplateSelector and apply it to the ItemTemplateSelector property of the TreeView. I can't find the URL where I found an example of it, but hopefully with this info, you can Google it.




回答2:


Another alternative (similar to jing's solution): If you only have one type of item, you can set the ItemTemplate directly. Then you don't need to set a key or a datatype.

In your ViewModel:

public ObservableCollection<IThing> Thingies { get; private set; }

In the View:

<TreeView ItemsSource="{Binding Thingies}">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding SomeThings}">
            <TextBox Text="{Binding SomeString}" />    
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>



回答3:


Another solution is you give a key to the HierarchicalDataTemplate and put it in the Windows.Resources, and manually reference to it in the TreeView. <TreeView ItemDataTemplate={StaticResource templateKey}/>

But that limits the autoselection of data template according to data type, which is provided by WPF TreeView.



来源:https://stackoverflow.com/questions/259063/wpf-hiercharchicaldatatemplate-datatype-how-to-react-on-interfaces

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!