11

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

<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,来实现DataTemplateDataTemplateSelector就像这样 -

<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

4 回答 4

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(还)

我不知道两者之间有任何显着的性能差异,但如果有人可以告诉我,我会很感兴趣。

于 2012-01-19T13:54:46.300 回答
3

你这里有两个问题:)

  1. XAML在( DataTriggers) 或代码中的何处做出决定TemplateSelector
  2. 你在覆盖整个Style还是只是DataTemplate. 在您覆盖的第一个示例Style中,在第二个示例中 - DataTemplate

这是我的2c:

我会坚持使用触发器,因为您将获得无与伦比的灵活性水平 - 新资源价格的新编辑器和 XAML 中的触发器 - 还有什么更好的?有一个与 DataTrigger 使用相关的潜在警告 - 它可能导致数据泄漏。

谈到StylevsDataTemplate选择,我再次坚持使用Style. 它可能是一个更重的视觉树明智,但它会让你最终控制你的编辑器的外观。

特别是,某些属性只能在一个Style级别上定义,使用Style Setters's. 然后定义 @ DataTemplatelevel 根本不起作用,因为您的DataTemplate内容不是您的控制容器的直接子级(还有一个额外的级别 - actula Control)。如果你没有这样的属性,ControlTemplates也很好,而且可能更快(?)。

于 2012-01-19T13:56:24.903 回答
1

I'm also not a fan of DataTemplateSelector, but I guess you could use them if your selector-evaluation consists of more than type checking, e.g. if x>5 && dayOfWeek==Tue && isFullMoon(today) then template1.

于 2019-01-09T12:01:35.677 回答
0

我建议答案更多是您认为control是否有必要。您可以通过 a 获得一大堆功能,controlDataTemplate. 您可以添加DependencyProperties,eventsfunctions。但是您需要这个吗?如果您不这样做,那么控件可能会矫枉过正。

于 2012-07-06T03:44:02.753 回答