是否有可能进行组合或继承(类似于样式中的“BasedOn”)? 我有两个需要这样做的情况。
对于继承类:我有一个带有多个继承类的基类。我不想在每个派生类的中重复基类模板。
不同的视图:对于相同的类,我想定义一个数据模板,然后根据需要添加到该模板中。例如,基本模板将显示对象中的数据,然后我想要不同的模板来对对象执行不同的操作,同时显示数据(继承基本模板)。
是否有可能进行组合或继承(类似于样式中的“BasedOn”)? 我有两个需要这样做的情况。
对于继承类:我有一个带有多个继承类的基类。我不想在每个派生类的中重复基类模板。
不同的视图:对于相同的类,我想定义一个数据模板,然后根据需要添加到该模板中。例如,基本模板将显示对象中的数据,然后我想要不同的模板来对对象执行不同的操作,同时显示数据(继承基本模板)。
我所发现的解决这种问题的唯一方法是:
<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上有一些关于此的讨论,但我没有看到有人提出更好的解决方案。
@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方式。可以使用DataTemplateSelector类来实现这一点,它会根据设置的任何条件选择数据模板。
例如,您可以轻松地设置一个模板,它查找已知的数据类型,并为这两种类型返回相同的DataTemplate,但对于其他所有类型,则回退到系统以解析DataTemplate。这就是我们在这里实际执行的操作。
希望这可以有所帮助! :)