我有一个通用控件,它根据ViewModel中的type属性显示一个编辑器。目前,它是使用Control
,ControlTemplate
和DataTrigger
这样实现的 -
<Control
x:Name="MainControl"
Grid.Column="1"
TargetUpdated="OnTargetUpdated">
<Control.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Bool}">
<Setter
Property="Control.Template"
Value="{StaticResource boolTemplate}" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Text}">
<Setter
Property="Control.Template"
Value="{StaticResource textTemplate}" />
</DataTrigger>
<DataTrigger
Binding="{Binding Path=EditorType}"
Value="{x:Static view:EditorType.Integer}">
<Setter
Property="Control.Template"
Value="{StaticResource integerTemplate}" />
</DataTrigger>
...
....
</Style.Triggers>
</Style>
</Control.Style>
</Control>
现在,使用ContentPresenter
,DataTemplate
和DataTemplateSelector
就可以实现同样的效果 -
<local:EditorTemplateSelector
BoolEditorTemplate="{StaticResource boolTemplate}"
TextEditorTemplate="{StaticResource textTemplate}"
IntegerEditorTemplate="{StaticResource integerTemplate}"
...
....
x:Key="EditorTemplateSelector">
</local:EditorTemplateSelector>
<ContentPresenter
ContentTemplateSelector="{Binding Source={StaticResource EditorTemplateSelector}}"
Content="{Binding}"
TargetUpdated="OnTargetUpdated">
</ContentPresenter>
// Template selector returning appropriate template based on type
我觉得第二种方法,使用DataTemplateSelector
更好,但想知道 -
哪一个更好,为什么?
两个会有任何性能差异吗?
答案 0 :(得分:9)
我听说DataTemplateSelectors
如果基于更改的值,则不会更新模板,因此我通常不会使用它们。
我首选的方法实际上是使用DataTemplates。
<MyControl.Resources>
<DataTemplate TargetType="{x:Type local:BooleanModel}">
<local:BooleanView />
</DataTemplate>
<DataTemplate TargetType="{x:Type local:IntegerModel}">
<local:IntegerView />
</DataTemplate>
...
</MyControl.Resources>
其次,如果我想基于属性而不是对象类型更改模板,我倾向于使用DataTriggers
。这是因为如果该属性发生变化,PropertyChange通知将自动告知UI它已更改并更新模板。我不相信DataTemplateSelectors
会自动执行此操作。我也更喜欢在我的XAML中看到模板选择逻辑,而不是将它隐藏在TemplateSelector文件中,但这只是个人偏好。
我最后的选择是使用DataTemplateSelector
。我几乎从不在WPF应用程序中使用过一个,尽管我经常在Silverlight中使用它,因为它不支持我使用隐式DataTemplates
的优选方法(还)
我不知道两者之间有任何显着的性能差异,但如果有人能告诉我,我会感兴趣。
答案 1 :(得分:3)
这里有两个问题:)
XAML
(DataTriggers
)或代码TemplateSelector
Style
还是DataTemplate
。在第一个示例中,您将覆盖Style
,在第二个示例中,DataTemplate
。这是我的2c:
我会坚持使用触发器,因为你将获得无与伦比的灵活性等级 - 新资源的价格和XAML中的触发器的新编辑器 - 什么可以更好?有一个潜在的警告,与DataTrigger的使用有关 - 它可能导致数据泄漏。
谈到Style
vs DataTemplate
选择我再次坚持使用Style
。这可能是一个更重的视觉树,但它会让你最终控制你的编辑的外观。
特别是,某些属性只能使用Style
Style
来定义Setters
级别。
然后定义@ DataTemplate
级别将无效,因为您的DataTemplate
内容不是您的控件容器的直接子级(有一个额外级别 - actula控件)。如果你没有这样的属性,ControlTemplates
也很好,而且可能更快(?)。
答案 2 :(得分:1)
我也不是DataTemplateSelector的粉丝,但是我猜如果您的选择器评估包括多于类型检查(例如, if x>5 && dayOfWeek==Tue && isFullMoon(today)
然后是template1。
答案 3 :(得分:0)
我建议答案更多的是你认为control
是必要的。您使用control
获得了一大堆功能DataTemplate
无法实现。您可以添加DependencyProperties
,events
,functions
等等。但是,您需要这个吗?如果你不这样做,那么控件可能会过度。