【问题标题】:WPF: Trigger for ListBoxItem.IsSelected not working for Background propertyWPF:ListBoxItem.IsSelected 的触发器不适用于 Background 属性
【发布时间】:2011-07-18 17:11:08
【问题描述】:

我尝试使用ListBoxItemContainerStyle 中的触发器更改我的ListBoxItems 的Background 属性,如下所示:

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

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

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

我有什么遗漏吗?这种行为是否记录在某处?

感谢任何提示!

编辑

我知道覆盖默认系统颜色的解决方案(如Change selected and unfocused Listbox style to not be grayed out 中所述,无论如何感谢大家将此作为答案发布)。然而,这不是我想要做的。我更感兴趣的是为什么我的解决方案不起作用。

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

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

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

【问题讨论】:

  • 这意味着您使用了正确的解决方案。没有标准 ControlTemplate 和没有画笔覆盖的解决方案。

标签: wpf background styles


【解决方案1】:

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

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

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

<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 触发器,它不会起作用,因为每个系统都有其默认的高亮画笔,具体取决于您的系统主题。

      您需要在代码中覆盖高亮画笔才能使其正常工作。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2014-05-14
          • 1970-01-01
          • 2016-09-13
          • 1970-01-01
          • 2016-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-24
          相关资源
          最近更新 更多