Подтвердить что ты не робот

WPF: триггер для ListBoxItem.IsSelected не работает для свойства Background

Я пытаюсь изменить свойство Background для моего ListBoxItem с помощью триггеров в ItemContainerStyle моего ListBox следующим образом:

    <ListBox Height="100" HorizontalAlignment="Left" Margin="107,59,0,0" Name="listBox1" VerticalAlignment="Top" Width="239">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Background" Value="Lightblue"/>
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter Property="Background" Value="Red"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" Value="Yellow"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.Items>
            <ListBoxItem Content="First Item"/>
            <ListBoxItem Content="SecondItem"/>
            <ListBoxItem Content="Third Item"/>
        </ListBox.Items>
    </ListBox>

Я ожидал бы, что у невыбранных элементов будет светло-синий фон, зависание элементов (т.е. когда курсор мыши над ними) будет желтым, а выбранные элементы будут красными.

Для невыделенных и зависающих элементов это работает так, как ожидалось, но выбранные элементы по-прежнему имеют свой стандартный цвет фона (то есть синий, если в списке есть фокус и светло-серый в противном случае).

Есть ли что-то, что мне не хватает? Является ли это поведение документированным где-то?

Спасибо за любой намек!

ИЗМЕНИТЬ

Я знаю о решении переопределить цвета системы по умолчанию (как описано в Изменить выбранный и не сфокусированный стиль списка, чтобы не было выделено серым цветом, спасибо в любом случае для всех отправляя это как ответ). Однако я не хочу этого делать. Меня больше интересует, почему мое решение не работает.

Я подозреваю, что стандартный ControlTemplate of ListItem определяет его собственные триггеры, которые, как представляется, воспринимают триггеры, определенные стилем (возможно, кто-то может подтвердить это и указать мне на какой-то ресурс, где это поведение определено),

Мое решение тем временем - определить ControlTemplate для моего ListItem как:

        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border Name="Border" Padding="2" SnapsToDevicePixels="true" Background="LightBlue" Margin="0">
                                <ContentPresenter/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="Border" Property="Background" Value="Red"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
4b9b3361

Ответ 1

Немного отразится на стиле Aero, и нам объясняется, почему эта простая настройка триггера не работает.

ListBoxItem имеет ControlTemplate с триггерами, которые имеют приоритет над нашим триггером. По крайней мере, это похоже на MultiTrigger. Мне удалось переопределить простой триггер Selected = true, но для мультитригера мне пришлось создать свой собственный ControlTemplate.

Это шаблон из стиля Aero, который показывает проблемный MultiTrigger:

<ControlTemplate TargetType="{x:Type ListBoxItem}">
    <ControlTemplate.Triggers>
        <Trigger Property="IsSelected" Value="true">
            <Setter TargetName="Bd" Value="{DynamicResource {x:Static HighlightBrush}}" Property="Background" />
            <Setter Value="{DynamicResource {x:Static HighlightTextBrush}}" Property="Foreground" />
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="true" />
                <Condition Property="IsSelectionActive" Value="false" />
            </MultiTrigger.Conditions>
            <Setter TargetName="Bd" Value="{DynamicResource {x:Static ControlBrush}}" Property="Background" />
            <Setter Value="{DynamicResource {x:Static ControlTextBrush}}" Property="Foreground" />
        </MultiTrigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Value="{DynamicResource {x:Static GrayTextBrush}}" Property="Foreground" />
        </Trigger>
    </ControlTemplate.Triggers>
    <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
    </Border>
</ControlTemplate>

Надеюсь, он немного разобрался. Я не могу понять, почему они слишком усложнили стиль.

Ответ 2

удалить триггер IsSelected И добавьте в список:

<ListBox.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                         Color="Red" />
    <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
                         Color="Red" />
</ListBox.Resources>

Первая кисть для сфокусированного секунды в противном случае

Ответ 3

Попробуйте добавить это к своим ресурсам окна -

 <Window.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                             Color="Red" />
 </Window.Resources>

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

Вам нужно переопределить выделенную кисть в коде, чтобы она работала.

Ответ 4

Попробуйте использовать Selector.IsSelected в вашем триггере, а не в IsSelected.