我收集了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>
是否有更好的(即无代理)方式?
答案 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提供的数据类型。