WPF – Как объединить DataTrigger и Trigger?
-
03-07-2019 - |
Вопрос
ПРИМЕЧАНИЕ Я задал соответствующий вопрос: Как объединить DataTrigger и EventTrigger?
У меня есть список, содержащий несколько элементов.Класс элемента реализует INotifyPropertyChanged
и имеет свойство IsAvailable
.Я использую это свойство, чтобы обозначить недоступные параметры в списке другим цветом.
Однако если выбранный элемент недоступен, цвет переднего плана должен быть красным.
<ListBox>
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:InstitutionViewModel}">
<TextBlock Name="Name" Text="{Binding Name}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsAvailable}" Value="False">
<Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.Resources>
</ListBox>
Я использую приведенный выше триггер данных, чтобы выделить недоступные элементы серым цветом.
Проблема, с которой я столкнулся, заключается в том, что тот факт, что элемент выбран, не имеет ничего общего с базовыми данными, к которым привязан шаблон.Что мне действительно нужно, так это какой-то мультитриггер, который поддерживает как обычный Trigger
на свойстве зависимости (ListBoxItem.IsSelected
) вместе с DataTrigger
на привязанном элементе данных.
Можно ли это сделать, не вводя концепцию выбора в мою модель представления?
Если вам интересно, почему я не отключаю недоступные элементы, поймите, что приложение требует возможности выбора недоступных параметров.На самом деле существует несколько списков, и выбор в одном из них влияет на то, что доступно в других.Я не могу отключить элементы, поскольку пользователь не сможет передумать или изучить различные комбинации, если элементы были отключены на основе предыдущего выбора.
Решение
Для всех, кто столкнулся с этой проблемой, я нашел решение, которое работает для меня.Конечно, мне все еще интересно увидеть другие интересные ответы.
Вот что я сделал:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding
RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" Value="True"/>
<Condition Binding="{Binding IsAvailable}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter TargetName="Name" Property="Foreground" Value="#F00"/>
</MultiDataTrigger>
Однако нет ничего особенного в том, что это мультитриггер.Если вы просто хотите по-другому стилизовать выбранный элемент в шаблоне данных, вы можете использовать:
<DataTrigger Binding="{Binding
RelativeSource={
RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}},
Path=IsSelected}" Value="True">
<Setter TargetName="Name" Property="Foreground" Value="#888"/>
</DataTrigger>
Другие советы
Чтобы использовать его с DataGridRow
изменить режим привязки на Self
:
Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=...