ControlTemplate с DataTrigger Vs. DataTemplate с DataTemplateSelector
У меня есть общий элемент управления, который отображает редактор, основанный на свойстве типа внутри 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
лучше, но хотел бы знать от вас -
Какой из них лучше и почему?
Будет ли разница в производительности в два раза?
3 ответа
Я слышал это 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
(еще)
Я не знаю каких-либо существенных различий в производительности между этими двумя, хотя мне было бы интересно, если кто-то может сказать мне иначе.
У вас есть два вопроса здесь:)
- Где сделать дексионирование в
XAML
(DataTriggers
) или в кодеTemplateSelector
- Что ты отвергаешь в целом
Style
или простоDataTemplate
, В вашем первом примере вы переопределяетеStyle
во втором -DataTemplate
,
Вот мой 2с:
Я бы придерживался триггеров, так как вы получите непревзойденный уровень гибкости с ними - новый редактор по цене нового ресурса и триггер в XAML - что может быть лучше? Есть одно потенциальное предупреждение, связанное с использованием DataTrigger - это может вызвать утечку данных.
Говоря о Style
против DataTemplate
выбор я придерживаться снова с Style
, Это может быть немного тяжелее визуального дерева, но это даст вам полный контроль над внешним видом ваших редакторов.
В частности, некоторые свойства могут быть определены только в Style
уровень, используя Style
Setters
"S. Определяя тогда @DataTemplate
уровень просто не будет работать как ваш DataTemplate
content не является непосредственным потомком вашего контейнера управления (есть дополнительный уровень - элемент управления). Если у вас нет таких свойств, ControlTemplates
тоже хорошо, и, вероятно, быстрее (?).
Я также не фанат DataTemplateSelector, но я думаю, вы могли бы использовать их, если ваша оценка селектора состоит не только из проверки типа, например if x>5 && dayOfWeek==Tue && isFullMoon(today)
тогда template1.
Я хотел бы предложить ответ больше один из вы думаете, control
является необходимым. Вы получаете целую кучу функциональности с control
это на самом деле не доступно с DataTemplate
, Можете добавить DependencyProperties
, events
, functions
и т. д. Но вам это нужно? Если вы этого не сделаете, контроль может быть излишним.