WPF HiercharchicalDataTemplate.DataType:如何对接口做出反应?

时间:2008-11-03 15:54:10

标签: wpf interface templates types

问题

我收集了IThing个帖子,我想为HierarchicalDataTemplate创建一个TreeView。直截了当DataType={x:Type local:IThing}当然不起作用,可能是因为WPF创建者不想处理可能的歧义。

由于这应该同时处理来自不同来源的IThing,因此引用实现类是不可能的。

当前解决方案

现在我正在使用一个ViewModel,它通过一个具体的实现来代理IThing:

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>

问题

是否有更好的(即无代理)方式?

3 个答案:

答案 0 :(得分:4)

另一种替代方法(类似于jing的解决方案):如果您只有一种类型的项目,则可以直接设置ItemTemplate。然后您不需要设置密钥或数据类型。

在ViewModel中:

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

在视图中:

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

答案 1 :(得分:3)

原因是默认模板选择器仅支持具体类型,而不支持接口。您需要创建自定义DataTemplateSelector并将其应用于TreeView的ItemTemplateSelector属性。我找不到我找到它的示例的网址,但希望通过此信息,您可以使用Google。

答案 2 :(得分:2)

另一个解决方案是为HierarchicalDataTemplate提供一个键并将其放在Windows.Resources中,并在TreeView中手动引用它。 <TreeView ItemDataTemplate={StaticResource templateKey}/>

但是这限制了数据模板的自动选择,这是由WPF TreeView提供的数据类型。