WPF VB.NET 如何通过传入行号列号移动到DataGrid指定单元格
WPF VB.NET 实现DataGrid指定行号列号单元格定位
默认行号、列号从0开始计数,执行定位前需确保DataGrid已完成数据源绑定、UI渲染完成。
核心实现代码
''' <summary> ''' 定位到DataGrid指定行号列号的单元格 ''' </summary> ''' <param name="dataGrid">目标DataGrid控件</param> ''' <param name="rowIndex">目标行号(从0开始)</param> ''' <param name="columnIndex">目标列号(从0开始)</param> Public Sub NavigateToDataGridCell(dataGrid As DataGrid, rowIndex As Integer, columnIndex As Integer) ' 校验参数合法性 If rowIndex < 0 OrElse rowIndex >= dataGrid.Items.Count Then Throw New ArgumentOutOfRangeException(NameOf(rowIndex), "行号超出有效范围") End If If columnIndex < 0 OrElse columnIndex >= dataGrid.Columns.Count Then Throw New ArgumentOutOfRangeException(NameOf(columnIndex), "列号超出有效范围") End If ' 先滚动到目标行,解决虚拟化场景下无法获取行对象的问题 dataGrid.ScrollIntoView(dataGrid.Items(rowIndex)) dataGrid.UpdateLayout() ' 获取目标行对象 Dim targetRow As DataGridRow = CType(dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex), DataGridRow) If targetRow Is Nothing Then Return ' 获取目标单元格 Dim targetCell As DataGridCell = GetDataGridCell(dataGrid, targetRow, columnIndex) If targetCell Is Nothing Then Return ' 选中并聚焦单元格 dataGrid.SelectedItem = dataGrid.Items(rowIndex) dataGrid.CurrentCell = New DataGridCellInfo(targetCell) targetCell.Focus() targetCell.IsSelected = True End Sub ''' <summary> ''' 辅助方法:获取指定行、列下的DataGridCell对象 ''' </summary> Private Function GetDataGridCell(dataGrid As DataGrid, targetRow As DataGridRow, columnIndex As Integer) As DataGridCell Dim presenter As DataGridCellsPresenter = FindVisualChild(Of DataGridCellsPresenter)(targetRow) If presenter Is Nothing Then ' 强制生成单元格容器 dataGrid.ScrollIntoView(targetRow, dataGrid.Columns(columnIndex)) dataGrid.UpdateLayout() presenter = FindVisualChild(Of DataGridCellsPresenter)(targetRow) End If Return CType(presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex), DataGridCell) End Function ''' <summary> ''' 辅助方法:查找可视化子元素 ''' </summary> Private Function FindVisualChild(Of T As DependencyObject)(obj As DependencyObject) As T For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj) - 1 Dim child As DependencyObject = VisualTreeHelper.GetChild(obj, i) If child IsNot Nothing AndAlso TypeOf child Is T Then Return CType(child, T) End If Dim childItem As T = FindVisualChild(Of T)(child) If childItem IsNot Nothing Then Return childItem End If Next Return Nothing End Function
调用示例
比如要定位到第3行(行号2)、第2列(列号1)的单元格,调用方式如下:
' 假设你的DataGrid控件名为MyDataGrid NavigateToDataGridCell(MyDataGrid, 2, 1)
注意事项
- 如果你业务中的行号/列号从1开始计数,调用方法前需要先将行号、列号减1再传入
- 如果DataGrid开启了列隐藏、列重排功能,需要先将业务列号映射为DataGrid.Columns的实际索引,避免定位错误
- 定位后如果需要直接进入单元格编辑状态,在
NavigateToDataGridCell方法末尾添加dataGrid.BeginEdit()即可 - 不要在窗口初始化的
Initialized、Loaded事件未完成时调用该方法,此时DataGrid的UI元素尚未生成,会导致定位失败
内容的提问来源于stack exchange,提问作者Muhammad Asim Awan
相关产品推荐
相关产品推荐

