ControlTemplate с DataTrigger Vs. DataTemplate с DataTemplateSelector - PullRequest
11 голосов
/ 19 января 2012

У меня есть общий элемент управления, который отображает редактор, основанный на свойстве типа внутри ViewModel.В настоящее время это реализовано с использованием 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, но хотел бы узнать от вас -

  • Какой из них лучше и почему?

  • Будет ли разница в производительности в два раза?

Ответы [ 4 ]

9 голосов
/ 19 января 2012

Я слышал, что 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 автоматически сообщит пользовательскому интерфейсу, что оно изменилось, и обновит шаблон.Я не верю DataTemplateSelectors сделать это автоматически.Я также предпочитаю видеть логику выбора шаблонов в моем XAML, не скрывать ее в файле TemplateSelector, но это просто личное предпочтение.

И мой последний выбор - использовать DataTemplateSelector.Я почти никогда не использую его в приложении WPF, хотя я часто использую его в Silverlight, поскольку он не поддерживает мой предпочтительный метод использования неявного DataTemplates (пока)

Я не знаю о каких-либо существенных различиях в производительности междудва, хотя мне было бы интересно, если кто-то может сказать мне иначе.

3 голосов
/ 19 января 2012

У вас есть два вопроса здесь:)

  1. Где сделать дешифровку в XAML (DataTriggers) или в коде TemplateSelector
  2. Что вы переопределяетевсе Style или просто DataTemplate.В первом примере вы переопределяете Style, во втором - DataTemplate.

Вот мой 2c:

Я бы придерживался триггеров, а выС ними вы получите непревзойденный уровень гибкости - новый редактор по цене нового ресурса и триггер в XAML - что может быть лучше?Есть одно потенциальное предостережение, связанное с использованием DataTrigger - это может привести к утечке данных.

Говоря о Style против DataTemplate, я снова придерживаюсь Style.Это может быть немного тяжелее визуального дерева, но оно даст вам полный контроль над внешним видом ваших редакторов.

В частности, некоторые свойства могут быть определены только на уровне Style, используя Style Setters х.Тогда определение уровня @ DataTemplate просто не сработает, поскольку ваш контент DataTemplate не является непосредственным потомком вашего контейнера управления (есть дополнительный уровень - элемент управления Actula).Если у вас нет таких свойств, ControlTemplates тоже хороши и, вероятно, быстрее (?).

1 голос
/ 09 января 2019

Я также не фанат DataTemplateSelector, но я думаю, вы могли бы использовать их, если ваша оценка селектора состоит из больше, чем проверка типа , например. if x>5 && dayOfWeek==Tue && isFullMoon(today) затем template1.

0 голосов
/ 06 июля 2012

Я бы посоветовал получить ответ, который, по вашему мнению, control необходим.Вы получаете целый набор функций с control, который на самом деле недоступен с DataTemplate.Вы можете добавить DependencyProperties, events, functions и т. Д. И т. Д. Но вам это нужно?Если вы этого не сделаете, контроль может быть излишним.

...