WPF:ListBoxItem.IsSelected 的触发器不适用于背景属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5361698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:40:44  来源:igfitidea点击:

WPF: Trigger for ListBoxItem.IsSelected not working for Background property

wpfbackgroundstyles

提问by MartinStettner

I try to change the Backgroundproperty for my ListBoxItems using triggers in the ItemContainerStyleof my ListBoxas follows:

我试图改变Background属性我ListBoxItem使用触发器在SItemContainerStyle的我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>

I would expect unselected items to have a light blue background, hovered items (i.e. when the mouse cursor is over them) to be yellow and selected items to be red.

我希望未选择的项目具有浅蓝色背景,悬停的项目(即当鼠标光标悬停在它们上方时)为黄色,选定的项目为红色。

For the unselected and hovered items this is working as expected, but the selected items still have their standard background color (i.e. blue, if the listbox has focus and light gray otherwise).

对于未选择和悬停的项目,这是按预期工作的,但所选项目仍然具有其标准背景颜色(即蓝色,如果列表框具有焦点,否则为浅灰色)。

Is there anything I'm missing? Is this behaviour documented somewhere?

有什么我想念的吗?这种行为是否记录在某处?

Thanks for any hint!

感谢您的任何提示!

EDIT

编辑

I'm aware of the solution of overriding the default system colors (as described in Change selected and unfocused Listbox style to not be grayed out, thanks anyway for everyone posting this as an answer). However this is not what I want to do. I'm more interested in why my solution doesn't work.

我知道覆盖默认系统颜色的解决方案(如将选定的和未聚焦的列表框样式更改为不灰显中所述,无论如何感谢每个人将此作为答案发布)。然而,这不是我想要做的。我对为什么我的解决方案不起作用更感兴趣。

I'm suspecting the standard ControlTemplateof ListItemto define it's own triggers which seem to take precendence over triggers defined by the style (perhaps someone could confirm this and point me to some resource where this behaviour is defined).

我怀疑标准ControlTemplateListItem定义它自己的触发器,这似乎采取precendence在由风格定义的触发器(也许有人可以证实这一点,并指出我的一些资源,其中这种行为被定义)。

My solution for the meantime is to define a ControlTemplatefor my ListItems like:

我的解决方案是ControlTemplate为我的ListItems定义一个:

        <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>

采纳答案by Almund

A little bit of reflecting on the Aero-style offers us an explanation to why this simple trigger-setting doesn't work.

对 Aero 风格的一些反思为我们解释了为什么这种简单的触发设置不起作用。

The ListBoxItem has a ControlTemplate with triggers that takes precedence over our trigger. At least this seems to be true for a MultiTrigger. I′ve managed to override the simple trigger of Selected=true but for the multitrigger I had to make my own ControlTemplate.

ListBoxItem 有一个 ControlTemplate,其触发器优先于我们的触发器。至少对于 MultiTrigger 来说,这似乎是正确的。我已经设法覆盖了 Selected=true 的简单触发器,但是对于多触发器,我必须制作自己的 ControlTemplate。

This is the template from the Aero style that shows the problematic MultiTrigger:

这是 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>

Hope it clears things up a little bit. I can't fathom why they′ve overcomplicated the style this much.

希望它能把事情弄清楚一点。我不明白为什么他们把风格搞得这么复杂。

回答by Sonorx

delete IsSelected trigger And add to listbox:

删除 IsSelected 触发器并添加到列表框:

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

First brush for focused second for otherwise

第一次刷重点第二次否则

回答by Rohit Vats

Try adding this to your window resources -

尝试将其添加到您的窗口资源中 -

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

And remove the IsSelected Trigger from your code, it won't work because every system has its default highlight brush depending on your system theme.

并从您的代码中删除 IsSelected 触发器,它不会起作用,因为每个系统都有其默认的高亮画笔,具体取决于您的系统主题。

You need to override the highlight brush in your code to make it work.

您需要覆盖代码中的高亮画笔以使其工作。

回答by Andrej

Try using Selector.IsSelected in your Trigger rather than IsSelected.

尝试在触发器中使用 Selector.IsSelected 而不是 IsSelected。