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

WinUI 3 CommunityToolkit DataGrid如何获取当前选中的DataGridCell实例

解决方案

方案1:直接在单元格层级绑定点击事件(推荐,更简单稳定)

该方案无需遍历可视化树,直接通过XAML配置给所有单元格绑定点击事件,触发时可直接拿到点击的单元格实例:
首先在DataGrid的XAML定义中添加单元格样式:

<controls:DataGrid x:Name="MyDataGrid"
                   ItemsSource="{x:Bind YourItemsSource}">
    <controls:DataGrid.CellStyle>
        <Style TargetType="controls:DataGridCell">
            <EventSetter Event="Tapped" Handler="DataGridCell_Tapped"/>
        </Style>
    </controls:DataGrid.CellStyle>
    <!-- 其余列定义等代码 -->
</controls:DataGrid>

后台事件处理代码如下:

private void DataGridCell_Tapped(object sender, TappedRoutedEventArgs e)
{
    var clickedCell = sender as DataGridCell;
    if (clickedCell == null) return;

    MenuFlyout flyout = new MenuFlyout();
    MenuFlyoutItem item = new MenuFlyoutItem();
    item.Text = "Test";
    flyout.Items.Add(item);

    flyout.ShowAt(clickedCell);
}

该方案性能更好,也不会受DataGrid虚拟化的影响,稳定性更高。

方案2:在CurrentCellChanged事件中通过可视化树查找单元格

如果你需要沿用CurrentCellChanged事件的实现逻辑,可以通过可视化树遍历的方式拿到选中的单元格:
首先实现一个通用的可视化树子元素查找辅助方法:

// 从指定父元素中查找指定类型的子元素
private T FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
    if (parent == null) return null;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        if (child is T target)
            return target;

        var result = FindVisualChild<T>(child);
        if (result != null)
            return result;
    }
    return null;
}

修改你的CurrentCellChanged事件代码如下:

private void MyDataGrid_CurrentCellChanged(object sender, System.EventArgs e)
{
    if (MyDataGrid.SelectedIndex < 0 || MyDataGrid.CurrentColumn == null)
        return;

    // 获取当前选中的行容器
    var rowContainer = MyDataGrid.ContainerFromIndex(MyDataGrid.SelectedIndex) as DataGridRow;
    if (rowContainer == null)
        return;

    // 从行容器中查找当前列对应的单元格
    var cellsPresenter = FindVisualChild<DataGridCellsPresenter>(rowContainer);
    if (cellsPresenter == null)
        return;

    var currentCell = cellsPresenter.ContainerFromColumn(MyDataGrid.CurrentColumn) as DataGridCell;
    if (currentCell == null)
        return;

    MenuFlyout flyout = new MenuFlyout();
    MenuFlyoutItem item = new MenuFlyoutItem();
    item.Text = "Test";
    flyout.Items.Add(item);

    flyout.ShowAt(currentCell);
}

注意如果开启了DataGrid的行虚拟化,滚动后选中离屏行时可能出现行容器查找失败的情况,该场景下优先使用方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:18:02