ControlTmplate与DataTrigger相比。 DataTemplate与DataTemplateSelector

时间:2012-01-19 12:29:38

标签: wpf datatemplate controltemplate datatrigger datatemplateselector

我有一个通用控件,它根据ViewModel中的type属性显示一个编辑器。目前,它是使用ControlControlTemplateDataTrigger这样实现的 -

<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>

现在,使用ContentPresenterDataTemplateDataTemplateSelector就可以实现同样的效果 -

<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更好,但想知道 -

  • 哪一个更好,为什么?

  • 两个会有任何性能差异吗?

4 个答案:

答案 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)

这里有两个问题:)

  1. XAMLDataTriggers)或代码TemplateSelector
  2. 中进行决策的位置
  3. 你在覆盖整个Style还是DataTemplate。在第一个示例中,您将覆盖Style,在第二个示例中,DataTemplate
  4. 这是我的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无法实现。您可以添加DependencyPropertieseventsfunctions等等。但是,您需要这个吗?如果你不这样做,那么控件可能会过度。