更改选定列表框项目的背景颜色

Posted

技术标签:

【中文标题】更改选定列表框项目的背景颜色【英文标题】:Change background color for selected ListBox item 【发布时间】:2011-01-09 10:33:48 【问题描述】:

到目前为止,这是我的 XAML。

<ScrollViewer Grid.Column="1" Grid.RowSpan="2">

    <ListBox   Background="Black" ItemsSource="Binding Path=ActiveLog" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Column="0" Grid.Row="0" Foreground="White">
                        <TextBlock >Date:</TextBlock>
                        <TextBlock  Text="Binding Path=LogDate"/>
                    </TextBlock>
                    <TextBlock Grid.Column="1" Grid.Row="0" Foreground="White">
                        <TextBlock >Severity:</TextBlock>
                        <TextBlock  Text="Binding Path=Severity"/>
                    </TextBlock>
                    <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Foreground="LightGray" Text="Binding Path=Message"></TextBlock>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Template>
            <ControlTemplate>
                <StackPanel Background="Black" IsItemsHost="True" >
                </StackPanel>
            </ControlTemplate>
        </ListBox.Template>

    </ListBox>
</ScrollViewer>

唯一的问题是所选项目的右侧有一个蓝色框。我认为有一种方法可以更改选择颜色,但我找不到它。

【问题讨论】:

【参考方案1】:
<UserControl.Resources>
    <Style x:Key="myLBStyle" TargetType="x:Type ListBoxItem">
        <Style.Resources>
            <SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey"
                             Color="Transparent"/>
        </Style.Resources>
    </Style>
</UserControl.Resources> 

<ListBox ItemsSource="Binding Path=FirstNames"
         ItemContainerStyle="StaticResource myLBStyle">  

你只是覆盖了listboxitem的样式(见:TargetType is ListBoxItem)

【讨论】:

这不再适用于在 ControlTemplate 触发器中使用静态颜色的 Windows-8。您必须派生基础 Style 并在这些触发器中指定覆盖的画笔或直接提供颜色。 ***.com/a/16820062/1834662 @Viv 这是否也适用于 .net 4.5 中的 wpf? @Gusdor 是的,对于 Windows-7 上的 .net4.5,ControlTemplate 使用 SystemColors 表示状态。但是在 Windows-8 中,它不再像 Here 解释的那样。每个操作系统版本的差异似乎比每个 .net 版本的差异更大【参考方案2】:

或者您可以将 HighlightBrushKey 直接应用到 ListBox。 Setter Property="Background" Value="Transparent" 不起作用。但我确实必须将前景设置为黑色。

<ListBox  ... >
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True" >
                    <Setter Property="FontWeight" Value="Bold" />
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="Foreground" Value="Black" />
                </Trigger>
            </Style.Triggers>
            <Style.Resources>
                <SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey" Color="Transparent"/>
            </Style.Resources>
        </Style>                
    </ListBox.ItemContainerStyle>
</ListBox>

【讨论】:

这个解决方案对我有用,但@juFo 的答案并不奏效,因为所有控件都提供透明,看不到任何文本。【参考方案3】:

您需要使用ListBox.ItemContainerStyle。

ListBox.ItemTemplate 指定项目的内容 应如何显示。但 WPF 仍将每个项目包装在 ListBoxItem 控件中,如果选中,默认情况下,该控件会将其背景设置为系统突出显示颜色。您无法停止 WPF 创建 ListBoxItem 控件,但您可以设置它们的样式 - 在您的情况下,将背景设置为始终为透明或黑色或其他 - 为此,您可以使用 ItemContainerStyle。

juFo's answer 展示了一种可能的实现方式,即在项目样式的上下文中“劫持”系统背景画笔资源;另一种可能更惯用的技术是使用 Setter 作为 Background 属性。

【讨论】:

好的,现在更有意义了。谢谢。 如果在 ItemContainerStyle 中只为 'IsSelected' 中的 'Background' 属性使用 'Setter' 则不起作用。它仍然使用系统突出显示颜色。 :( 要更改所选ListBoxItem的背景颜色,您需要重新模板ListBoxItem。参考:here 中接受的答案中的评论。 VS 2012,.Net 框架 4.5。 您能否提供一个基于 ListBox.ItemContainerStyle 的解决方案的工作示例?似乎它不起作用,唯一可行的解​​决方案(不是基于系统颜色)是重新模板。【参考方案4】:

我必须同时设置 HighlightBrushKey 和 ControlBrushKey 才能正确设置样式。否则,虽然它有焦点,但它将正确使用透明的 HighlightBrusKey。顺便说一句,如果控件失去焦点(但仍突出显示),则它使用 ControlBrushKey。

<Style.Resources>
    <SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey" Color="Transparent" />
    <SolidColorBrush x:Key="x:Static SystemColors.ControlBrushKey" Color="Transparent" />
</Style.Resources>

使用 .Net 4.5 及更高版本时,请使用 InactiveSelectionHighlightBrushKey 而不是 ControlBrushKey

<Style.Resources>
    <SolidColorBrush x:Key="x:Static SystemColors.HighlightBrushKey" Color="Transparent" />
    <SolidColorBrush x:Key="x:Static SystemColors.InactiveSelectionHighlightBrushKey" Color="Transparent" />
</Style.Resources>

希望这对某人有所帮助。

【讨论】:

这对我帮助很大。我不知道 ListBox 没有聚焦时使用的 SystemColors 画笔是什么:) +1 这对我在右键单击时使背景透明非常重要。谢谢! 使用 InactiveSelectionHighlightBrushKey 而不是 .NET 4.5 中的 ControlBrushKey。【参考方案5】:

您必须像这样为项目选择创建一个新模板。

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListBoxItem">
            <Border
                BorderThickness="TemplateBinding Border.BorderThickness"
                Padding="TemplateBinding Control.Padding"
                BorderBrush="TemplateBinding Border.BorderBrush"
                Background="TemplateBinding Panel.Background"
                SnapsToDevicePixels="True">
                <ContentPresenter
                    Content="TemplateBinding ContentControl.Content"
                    ContentTemplate="TemplateBinding ContentControl.ContentTemplate"
                    HorizontalAlignment="TemplateBinding Control.HorizontalContentAlignment"
                    VerticalAlignment="TemplateBinding Control.VerticalContentAlignment"
                    SnapsToDevicePixels="TemplateBinding UIElement.SnapsToDevicePixels" />
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

【讨论】:

一个好的答案不仅仅是一个有效的答案,OP应该理解他的错误,而不是仅仅复制粘贴。否则他/她会在一周后回来在不同的环境中问同样的问题......【参考方案6】:

如果选择不重要,最好使用包装在 ScrollViewer 中的 ItemsControl。这种组合比 Listbox(实际上已经从 ItemsControl 派生)更轻量级,并且使用它可以消除使用廉价 hack 来覆盖 ItemsControl 中已经不存在的行为的需要。

如果选择行为实际上很重要,那么这显然行不通。但是,如果您想以一种对用户不可见的方式更改所选项目背景的颜色,那么这只会使他们感到困惑。如果您打算更改某些其他特征以表明该项目已被选中,那么此问题的其他一些答案可能仍然更相关。

这是标记的外观骨架:

    <ScrollViewer>
        <ItemsControl>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    ...
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>

【讨论】:

【参考方案7】:

我尝试了各种解决方案,但没有一个适合我,经过更多研究后,我在这里找到了适合我的解决方案

https://gist.github.com/LGM-AdrianHum/c8cb125bc493c1ccac99b4098c7eeb60

   <Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="_Border"
                                Padding="2"
                                SnapsToDevicePixels="true">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter TargetName="_Border" Property="Background" Value="Yellow"/>
                                <Setter Property="Foreground" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

 <ListBox ItemContainerStyle="DynamicResource _ListBoxItemStyle"
                 Width="200" Height="250"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 ScrollViewer.HorizontalScrollBarVisibility="Auto">
            <ListBoxItem>Hello</ListBoxItem>
            <ListBoxItem>Hi</ListBoxItem>
        </ListBox>

我把它贴在这里,因为这是这个问题的第一个谷歌结果,所以其他人可能会觉得它很有用。

【讨论】:

以上是关于更改选定列表框项目的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何通过Powershell代码更改特定WPF列表框项的背景颜色?

即使焦点在另一个控件上,如何更改列表视图选定的行背景颜色?

聚合物1.2:更改纸张选定的背景颜色

Flutter:更改 ListView.builder 中选定按钮的背景颜色

ListView:如何从列表中访问视图以更改背景颜色?

iOS 14,Swift UI 2 更改 NavigationLink 内选定列表项的背景颜色