WPF:ListBoxItem.IsSelected 的触发器不适用于 Background 属性 [英] WPF: Trigger for ListBoxItem.IsSelected not working for Background property

查看:27
本文介绍了WPF:ListBoxItem.IsSelected 的触发器不适用于 Background 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 ListBoxItemContainerStyle 中的触发器更改我的 ListBoxItemBackground 属性如下:

I try to change the Background property for my ListBoxItems using triggers in the ItemContainerStyle of my ListBox as follows:

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

感谢任何提示!

编辑

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

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.

我怀疑 ListItem 的标准 ControlTemplate 定义它自己的触发器,这些触发器似乎优先于由样式定义的触发器(也许有人可以确认这一点并指出我到一些定义了这种行为的资源).

I'm suspecting the standard ControlTemplate of ListItem to 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).

与此同时,我的解决方案是为我的 ListItem 定义一个 ControlTemplate,例如:

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

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

推荐答案

稍微反思一下 Aero 风格就可以解释为什么这个简单的触发器设置不起作用.

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

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

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.

这是显示有问题的 MultiTrigger 的 Aero 样式的模板:

This is the template from the Aero style that shows the problematic 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.

这篇关于WPF:ListBoxItem.IsSelected 的触发器不适用于 Background 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆