2015-11-11 3 views
0

У меня есть объект в ViewModel, свойства которого отображаются на datatemplate. Экран также имеет кнопку переключив IsEditing флаг в ViewModel, который должен сделать свойства объекта для редактирования, как следующее:Переключить два разных элемента в DataTemplate с помощью стильных триггеров

  • Имя должно измениться с TextBlock на TextBox;
  • Цвет должен меняться от цветного прямоугольника до ComboBox с возможностью выбора цвета;
  • Категория должна изменяться с TextBlock на ComboBox;

Я знаю, как осуществить это с двумя полностью независимыми DataTemplates, используя стиль и DataTrigger для переключения между ними:

<ContentControl Content="{Binding FancyObject}"> 
    <ContentControl.Style> 
     <Style TargetType="ContentControl"> 
      <Setter Property="ContentTemplate" Value="{StaticResource DisplayTemplate}"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding DataContext.IsEditing, ElementName=UserControl}" Value="True"> 
        <Setter Property="ContentTemplate" Value="{StaticResource EditTemplate}"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ContentControl.Style> 
</ContentControl> 

И в настоящее время DisplayTemplate, как это:

<DataTemplate x:Key="DisplayTemplate" DataType="my:FancyObject"> 
    <Border> 
     <DockPanel DataContext="{Binding Metadata}"> 
      <Border> 
       <TextBlock Text="{Binding Name}"/> 
      </Border>   
      <DataGrid 
       AutoGenerateColumns="False" 
       ItemsSource="{Binding FancyObjectCollection}"> 
       <DataGrid.Columns> 
        <!-- Text and Template columns --> 
       </DataGrid.Columns> 
      </DataGrid> 
     </DockPanel> 
    </Border>     
</DataTemplate> 

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

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

ответ

1

Вы можете использовать один шаблон. В шаблоне добавьте TextBlock и TextBox, то же самое для всех других элементов управления в исходном шаблоне. Привяжите видимость элементов управления к bool к конвертеру видимости. (Или используйте триггеры) Только один набор вашего контроля будет отображаться каждый раз (на основе флага IsEditing)

+0

Хм, это хорошая идея! Я получил рабочий вариант, используя 'ContentControl' со Стилем (как пример в моем вопросе) для КАЖДОГО поля в форме, но это быстро стало беспорядком! Ваша альтернатива намного лучше! Будете думать об этом завтра на работе, а затем приступить к публикации некоторых отзывов. Большое спасибо! – heltonbiker

+0

Ваше решение прост и решило проблему, избегая МНОГО шаблона ... Спасибо! – heltonbiker

+0

(ну, но в конце я сразу использовал один ComboBox, только в стиле, который выглядит как TextBlock при отключении, делая прозрачный фон и рамку). – heltonbiker

0

ControlTemplate используется только при создании элементов пользовательского интерфейса. Если вы измените шаблон ПОСЛЕ создания элементов, сгенерированные элементы не изменятся.

Вы также не можете использовать триггер, чтобы изменить TextBox на TextBlock и наоборот.

Ваш единственный вариант состоит в том, чтобы зеркально отобразить макет дважды и скрыть/отобразить его с помощью свойства привязки данных.