有没有办法在WPF中使用数据模板继承?

问题描述 投票:0回答:2

是否可以有

DataTemplate
组合或继承(类似于Styles中的“BasedOn”)?有 2 个实例我需要它。

  1. 对于继承类:我有一个带有几个继承类的基类。我不想在每个派生类的

    DataTemplate
    中重复基类模板。

  2. 不同的视图:对于同一个类,我想定义一个数据模板,然后根据需要添加到该模板。前任。基本模板将显示对象中的数据,然后我想要不同的模板,可以在显示数据的同时对对象执行不同的操作(继承基本模板)。

wpf xaml datatemplate
2个回答
54
投票

我发现做这种事情的唯一方法是:

<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上对此进行了一些讨论,但没有人提出我看到的更好的解决方案。


25
投票

@Fragilerus 和 @Liz,实际上我认为我确实想出了更好的东西。 这是另一种方法,不仅避免了额外的 ContentPresenter 绑定,而且还不需要在模板中应用模板,因为共享内容是在编译时设置的直接内容。 运行时发生的唯一事情是您在直接内容中设置的绑定。因此,与其他解决方案相比,这大大加快了 UI 速度。

<!-- 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 的方式

如上所述,这确实不是最适合 WPF 的方式来完成您想要的操作。 这可以使用 DataTemplateSelector 类来实现,该类正是这样做的...... select 是一个基于您设置的任何标准的数据模板。

例如,您可以轻松设置一个查找已知数据类型并为它们返回相同的 DataTemplate,但对于所有其他类型,它会回退到系统来解析 DataTemplate。 这就是我们在这里实际做的事情。

希望这有帮助! :)

© www.soinside.com 2019 - 2024. All rights reserved.