更改选定列表框项目的背景颜色
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列表框项的背景颜色?