是否可以拥有DataTemplate
组合或继承(类似于样式中的“BasedOn”)?有两个我需要的实例。
对于继承的类:我有一个带有几个继承类的基类。我不想在每个派生类的DataTemplate
中复制基类模板。
不同的视图:对于同一个类,我想定义一个datatemplate,然后根据需要添加到该模板。防爆。基础模板将显示对象中的数据,然后我想要不同的模板,可以对对象执行不同的操作,同时显示数据(继承基础模板)。
答案 0 :(得分:43)
我发现这件事的唯一目的是:
<DataTemplate x:Key="BaseClass">
<!-- base class template here -->
</DataTemplate>
<DataTemplate DataType="{x:Type app:BaseClass}">
<ContentPresenter Content="{Binding}"
ContentTemplate="{StaticResource BaseClass}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type app:DerivedClass}">
<StackPanel>
<ContentPresenter Content="{Binding}"
ContentTemplate="{StaticResource BaseClass}"/>
<!-- derived class extra template here -->
</StackPanel>
</DataTemplate>
基本上,这会创建一个可以使用键引用的“公共”模板(在本例中为BaseClass)。然后我们为基类和任何派生类定义真正的DataTemplate。派生类模板然后会添加它自己的“东西”。
前一段时间msdn对此进行了一些讨论,但没有人想出更好的解决方案。
答案 1 :(得分:22)
@Fragilerus和@Liz,实际上我觉得我确实想出了更好的东西。这是另一种方法,它不仅避免了额外的ContentPresenter绑定,而且还消除了在模板中应用模板的需要,因为共享内容是在编译时设置的直接内容。在运行时发生的唯一事情是您在直接内容中设置的绑定。因此,与其他解决方案相比,这大大加快了用户界面。
<!-- Content for the template (note: not a template itself) -->
<Border x:Shared="False"
x:Key="Foo"
BorderBrush="Red"
BorderThickness="1"
CornerRadius="4">
<TextBlock Text="{Binding SomeProp}" />
</Border>
<DataTemplate x:Key="TemplateA">
<!-- Static resource - No binding needed -->
<ContentPresenter Content="{StaticResource Foo}" />
</DataTemplate>
<DataTemplate x:Key="TemplateB">
<!-- Static resource - No binding needed -->
<ContentPresenter Content="{StaticResource Foo}" />
</DataTemplate>
重要提示:请确保在共享内容上使用x:Shared
属性,否则无效。
上面说过,这真的不是WPF最友好的方式来做你想要的事情。这可以使用DataTemplateSelector类来实现,该类完全正确...根据您设置的标准选择数据模板。
例如,您可以轻松地设置一个查找已知数据类型并为它们返回相同的DataTemplate,但对于所有其他类型,它会回退到系统以解析DataTemplate。这就是我们在这里真正做的事情。
希望这有帮助! :)