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

WPF DataGrid行MouseOver事件实现:行内按钮仅悬停显示问题咨询

在WPF DataGrid中实现行悬停时显示按钮

当然可以实现这个需求!而且不用费劲写后台的MouseOver事件处理逻辑——WPF的样式触发器(Trigger)天生就是干这个的,用声明式的XAML就能搞定,比后台代码优雅多了。

核心思路是:

  • 让按钮默认处于隐藏状态(Visibility="Collapsed")
  • 绑定按钮的可见性到所在行的IsMouseOver属性,当行被鼠标悬停时切换按钮为显示状态

下面给你两种可行的实现方案,你可以根据自己的场景选择:

方案一:轻量版(推荐)

直接在按钮所在的CellTemplate里添加触发器,绑定到父级DataGridRow的IsMouseOver属性,不需要修改行的整体模板:

<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <!-- 其他数据列 -->
        <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
        <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
        
        <!-- 带悬停显示按钮的操作列 -->
        <DataGridTemplateColumn Header="操作">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Button x:Name="EditBtn" Content="编辑" Margin="2,0"/>
                        <Button x:Name="DeleteBtn" Content="删除" Margin="2,0"/>
                    </StackPanel>
                    <DataTemplate.Triggers>
                        <!-- 当行未被悬停时隐藏按钮 -->
                        <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=DataGridRow}}" Value="False">
                            <Setter TargetName="EditBtn" Property="Visibility" Value="Collapsed"/>
                            <Setter TargetName="DeleteBtn" Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

方案二:自定义行模板版

如果你需要同时修改行的其他视觉状态(比如悬停时的背景色),可以重写DataGridRow的模板,在模板内添加触发器控制按钮显示:

<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="姓名" Binding="{Binding Name}" />
        <DataGridTextColumn Header="年龄" Binding="{Binding Age}" />
        
        <DataGridTemplateColumn Header="操作">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Button x:Name="EditBtn" Content="编辑" Margin="2,0" Visibility="Collapsed"/>
                        <Button x:Name="DeleteBtn" Content="删除" Margin="2,0" Visibility="Collapsed"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>

    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridRow">
                        <Border x:Name="RowBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                            <SelectiveScrollingGrid>
                                <DataGridCellsPresenter Grid.Column="1" />
                                <DataGridRowHeader Grid.RowSpan="2" />
                            </SelectiveScrollingGrid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <!-- 鼠标悬停时显示按钮并高亮行背景 -->
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="RowBorder" Property="Background" Value="#FFE5F3FF"/>
                                <Setter TargetName="EditBtn" Property="Visibility" Value="Visible"/>
                                <Setter TargetName="DeleteBtn" Property="Visibility" Value="Visible"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.RowStyle>
</DataGrid>

至于你之前尝试的后台MouseOver事件没生效,大概率是因为DataGrid默认开启了行虚拟化,直接绑定事件会因为行的复用机制出现异常——而用XAML触发器就完全避开了这个问题,它是跟着行的视觉状态自动同步的,稳定性更高。

内容的提问来源于stack exchange,提问作者Marcos Brinner pikatoons

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:49:36