ПРИМЕЧАНИЕ . Я задал связанный вопрос: Как объединить 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 для связанного элемента данных.

Можно ли это сделать без введения концепции выбора в мою модель представления?

Тем, кто задается вопросом, почему я не отключаю недоступные элементы, следует понимать, что это требование приложения, чтобы можно было выбирать недоступные параметры. На самом деле есть несколько списков, и выбор в одном из них влияет на то, что доступно в других. Я не могу отключить элементы, так как пользователь не сможет изменить свое мнение или изучить различные комбинации, если элементы были отключены на основании ранее сделанного выбора.

55
Drew Noakes 2 Мар 2009 в 17:25

2 ответа

Лучший ответ

Для всех, кто сталкивается с этой проблемой, я нашел решение, которое работает для меня. Конечно, мне все еще интересно увидеть другие интересные ответы.

Вот что я сделал:

<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>
75
Drew Noakes 2 Мар 2009 в 18:05
2
Это именно то, что я собирался порекомендовать. Насколько я знаю, это лучшее решение.
 – 
Bryan Anderson
2 Мар 2009 в 18:28
Просто ударьте ту же проблему. Отличный чувак, забыл об относительной привязке источника.
 – 
EightyOne Unite
7 Окт 2009 в 15:22

Чтобы использовать его с DataGridRow, измените режим привязки на Self:

Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=... 
18
Drew Noakes 1 Дек 2010 в 07:49
Кроме того, если вы пытаетесь использовать Path=Selector.IsSelectionActive, вместо этого используйте Path=(Selector.IsSelectionActive), потому что это присоединенное свойство.
 – 
Andrew
18 Ноя 2019 в 13:22