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
相关产品推荐
相关产品推荐

