You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何移除WPF ListViewItem样式中IsMouseOver的渐变效果?

解决DataGrid Row鼠标悬停时的渐变背景问题

嘿,我懂你的困扰——给DataGridRow的IsMouseOver触发器设置了背景色,结果还是冒出讨厌的渐变效果对吧?这是因为WPF默认的DataGridRow模板里,鼠标悬停状态自带了渐变画刷的视觉状态,就算你在触发器里设了纯色,也会被模板里的渐变给覆盖掉。

要搞定这个问题,你只需要把Theme.DataGrid.Row.Background.Hover这个资源直接内嵌到当前代码里,替换掉默认的渐变画刷,同时让你的触发器能正确覆盖默认样式就行。下面是具体的实现步骤和代码示例:

步骤1:在当前XAML中定义纯色的Hover背景画刷

把原本放在单独样式文件里的Theme.DataGrid.Row.Background.Hover移到当前DataGrid的资源块中,设置成你想要的纯色:

<DataGrid x:Name="YourDataGrid" ItemsSource="{Binding YourItems}">
    <DataGrid.Resources>
        <!-- 迁移原Theme资源,设置为纯色Brush -->
        <SolidColorBrush x:Key="Theme.DataGrid.Row.Background.Hover" Color="#FFE5F1FB" />
    </DataGrid.Resources>

步骤2:重写DataGridRow样式,确保触发器用纯色背景

接下来给DataGrid设置RowStyle,在IsMouseOver触发器里直接引用这个纯色画刷,彻底覆盖默认的渐变效果。这里有两种实用方式:

方式一:快速修改触发器(适合简单场景)

如果你的RowStyle不需要复杂模板,直接在触发器里设置Background为纯色画刷,就能覆盖默认渐变:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <!-- 使用我们定义的纯色Hover背景 -->
                <Setter Property="Background" Value="{StaticResource Theme.DataGrid.Row.Background.Hover}" />
                <!-- 可选:如果默认有边框渐变,也可以同步设置纯色边框 -->
                <Setter Property="BorderBrush" Value="#FFBCDFF1" />
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.RowStyle>

方式二:完全重写Row模板(彻底掌控样式)

如果默认模板还是在捣乱,你可以完全重写DataGridRow的ControlTemplate,移除所有渐变相关的视觉状态:

<DataGrid.RowStyle>
    <Style TargetType="DataGridRow">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridRow">
                    <Border x:Name="DGR_Border" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="True">
                        <SelectiveScrollingGrid>
                            <SelectiveScrollingGrid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </SelectiveScrollingGrid.ColumnDefinitions>
                            <SelectiveScrollingGrid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </SelectiveScrollingGrid.RowDefinitions>
                            <DataGridCellsPresenter Grid.Column="1" ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                            <DataGridDetailsPresenter Grid.Column="1" Grid.Row="1" Visibility="{TemplateBinding DetailsVisibility}" SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen, ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, Converter={x:Static DataGrid.RowDetailsScrollingConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                            <DataGridRowHeader Grid.RowSpan="2" SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Row}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                        </SelectiveScrollingGrid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="DGR_Border" Property="Background" Value="{StaticResource Theme.DataGrid.Row.Background.Hover}" />
                        </Trigger>
                        <!-- 可保留其他需要的触发器,比如选中状态 -->
                        <Trigger Property="IsSelected" Value="True">
                            <Setter TargetName="DGR_Border" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.RowStyle>

原理说明

默认的DataGridRow模板里有VisualStateManager,其中MouseOver状态会应用渐变背景。通过直接在触发器里设置Background(或者重写模板移除渐变视觉状态),我们的纯色画刷会优先于默认渐变生效。

另外你提到的自定义ViewModel(带PropertyChanged)不需要做任何修改,这个问题完全是WPF样式层面的,和数据绑定逻辑无关。

内容的提问来源于stack exchange,提问作者char m

火山引擎 最新活动