WPF问题:ListViewItem选中或悬停时背景/前景无法修改
WPF ListViewItem 悬停/选中样式不生效问题
我在WPF程序中使用ListView,希望实现鼠标悬停或选中ListViewItem时修改其样式。当前使用的代码如下:
<Style TargetType="ListViewItem"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Background" Value="White"/> <Setter Property="Foreground" Value="#1A1A1A"/> <Setter Property="FontWeight" Value="Bold"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderThickness" Value="0"/> <Setter Property="Background" Value="White"/> <Setter Property="Foreground" Value="#1A1A1A"/> </Trigger> </Style.Triggers> </Style>
但实际仅边框厚度和字体粗细生效,背景与前景完全无变化。我尝试过以下方案:
<Window.Resources> <Style TargetType="ListViewItem"> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/> </Style.Resources> </Style> </Window.Resources>
还尝试过禁用Focusable,但会丢失原有功能,目前未找到有效解决办法。
问题原因
WPF的ListViewItem默认模板通过VisualStateManager管理选中、悬停等状态的样式,这些内置状态设置的Background和Foreground优先级高于Style触发器中的设置,所以直接在触发器里修改不会生效。
解决方法
方法一:覆盖系统默认画刷
通过替换系统内置的选中/悬停相关画刷,让默认模板使用自定义的颜色,同时保留触发器中的其他样式设置:
<Style TargetType="ListViewItem"> <!-- 覆盖系统默认的状态画刷 --> <Style.Resources> <!-- 选中时的背景 --> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White"/> <!-- 失去焦点时的选中背景 --> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="White"/> <!-- 选中时的前景 --> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#1A1A1A"/> <!-- 失去焦点时的选中前景 --> <SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="#1A1A1A"/> <!-- 鼠标悬停时的背景 --> <SolidColorBrush x:Key="{x:Static SystemColors.MouseOverBrushKey}" Color="White"/> </Style.Resources> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="BorderThickness" Value="0"/> <Setter Property="FontWeight" Value="Bold"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderThickness" Value="0"/> </Trigger> </Style.Triggers> </Style>
方法二:重写ControlTemplate
如果需要完全自定义样式逻辑,可以直接重写ListViewItem的ControlTemplate,直接控制各个状态下的元素样式:
<Style TargetType="ListViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <Border x:Name="itemBorder" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter TargetName="itemBorder" Property="Background" Value="White"/> <Setter Property="Foreground" Value="#1A1A1A"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="BorderThickness" Value="0"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="itemBorder" Property="Background" Value="White"/> <Setter Property="Foreground" Value="#1A1A1A"/> <Setter Property="BorderThickness" Value="0"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
内容的提问来源于stack exchange,提问作者Dutch Van Der Linde
相关产品推荐
相关产品推荐

