You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WINUI3/UWP中如何设置DataGrid行鼠标悬停时背景透明?

在WINUI3的Community Toolkit DataGrid中设置行鼠标悬停背景为透明

推荐方案:通过XAML样式修改视觉状态

无需编写后台代码,直接修改DataGridRow的样式覆盖鼠标悬停(PointerOver)状态的背景,这是最符合WINUI设计模式的方式,还能避免反射带来的版本兼容性问题:

<Page.Resources>
    <!-- 引用Community Toolkit命名空间 -->
    <xmlns:controls="using:CommunityToolkit.WinUI.UI.Controls"/>

    <Style TargetType="controls:DataGridRow">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:DataGridRow">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <!-- 鼠标悬停状态:设置背景为透明 -->
                                <VisualState x:Name="PointerOver">
                                    <VisualState.Setters>
                                        <Setter Target="RootGrid.Background" Value="Transparent"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <!-- 可选:同时修改选中行的背景为透明 -->
                                <VisualState x:Name="Selected">
                                    <VisualState.Setters>
                                        <Setter Target="RootGrid.Background" Value="Transparent"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="SelectedUnfocused">
                                    <VisualState.Setters>
                                        <Setter Target="RootGrid.Background" Value="Transparent"/>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                            <ContentPresenter Content="{TemplateBinding Content}"/>
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

代码方式(修正版)

如果坚持用后台代码实现,需要修正原代码的核心问题,确保只修改当前悬停行的背景,并正确处理状态恢复:

using CommunityToolkit.WinUI.UI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Controls;

public DataGridControl()
{
    this.Loaded += DataGridControl_Loaded;
}

private void DataGridControl_Loaded(object sender, RoutedEventArgs e)
{
    if (sender is not DataGrid dataGrid) return;

    // 监听行容器生成事件,确保新添加的行也能绑定事件
    dataGrid.ItemContainerGenerator.ItemsChanged += ItemContainerGenerator_ItemsChanged;
    // 初始化已存在的行事件绑定
    BindRowEvents(dataGrid);
}

private void ItemContainerGenerator_ItemsChanged(object? sender, ItemsChangedEventArgs e)
{
    if (sender is ItemContainerGenerator generator && generator.ContainerFromIndex(0) is DataGridRow row)
    {
        var dataGrid = row.FindParent<DataGrid>();
        BindRowEvents(dataGrid);
    }
}

private void BindRowEvents(DataGrid dataGrid)
{
    foreach (var row in dataGrid.FindDescendants().OfType<DataGridRow>())
    {
        // 避免重复绑定事件
        row.PointerEntered -= Row_PointerEntered;
        row.PointerEntered += Row_PointerEntered;
        row.PointerExited -= Row_PointerExited;
        row.PointerExited += Row_PointerExited;
    }
}

private void Row_PointerEntered(object sender, PointerRoutedEventArgs e)
{
    if (sender is DataGridRow row && !row.IsSelected)
    {
        row.Background = new SolidColorBrush(Windows.UI.Colors.Transparent);
    }
}

private void Row_PointerExited(object sender, PointerRoutedEventArgs e)
{
    if (sender is DataGridRow row && !row.IsSelected)
    {
        // 恢复为DataGrid的背景色,或自定义默认背景
        row.Background = this.Background;
    }
}

原代码的问题说明

  • 监听整个DataGrid的PointerEntered事件会导致鼠标进入时所有行背景被修改,而非当前悬停的行
  • 错误使用反射访问IsSelected,该属性是DataGridRow的公开成员,可直接调用
  • 缺少PointerExited事件处理,鼠标离开行后无法恢复默认背景

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 15:52:50