9

У меня есть общий элемент управления, который отображает редактор, основанный на свойстве типа внутри ViewModel. В настоящее время это реализовано с использованием Control, ControlTemplate и DataTrigger как это -ControlTemplate с DataTrigger Vs. DataTemplate с DataTemplateSelector

<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

Из того, что я собираю, второй способ считается лучшей практикой. Он также намного читабельнее, так как в нем нет логики выбора (которая всегда должна быть определена в C#). Тем не менее, я заинтересован в производительности. –

ответ

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

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

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

+0

Интересно, я почти уверен, что вопрос был о WPF, просто из любопытства - они исправили неявные шаблоны в SL4/5, поскольку я знаю, что они не были доступны в предыдущих версиях. –

+0

@Dmitry Я считаю, что последний проект Silverlight, который я сделал, был в 4.0, и неявные DataTemplates не работали тогда. Я слышал, что они работают в 5.0, но пока этого не произошло. – Rachel

+0

+1 для 'DataTemplateSelectors не обновляют шаблон, если значение, на котором они основаны на chan'. Я проверил это, и шаблон не обновляется, если значение изменяется. Благодарю. – akjoshi

3

Вы имеете два вопроса здесь :)

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

Here're мой 2с:

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

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

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

+0

Спасибо, Дмитрий, можете ли вы предоставить более подробную информацию о 'DataTrigger вызывая утечку данных "? – akjoshi

+0

@akjoshi - Извините, я не смогу придумать точный репрограммирование, это скорее наблюдение, я видел несколько проектов, которые приносят пользу после сокращения количества триггеров. –

0

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

Смежные вопросы