Переключить два разных элемента в DataTemplate с помощью триггеров стилей

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

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

Я знаю, как реализовать это с двумя полностью независимыми DataTemplates, используя Style и 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>

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

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

2 ответа

Решение

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

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

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

Единственный вариант - дважды отразить макет и скрыть / отобразить его через свойство привязки данных.

Другие вопросы по тегам