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

WPF DataGrid:高效获取单元格所在行索引的方法

Efficiently Get Row Index from DataGridCellInfo Using Internal ItemInfo Property

Nice find! You’re right that most common solutions for grabbing a row index from DataGridCellInfo rely on slow linear searches (like Items.IndexOf(cellInfo.Item)), which get painful with large datasets. Leveraging the internal ItemInfo property is a smart way to skip that overhead—here’s how to implement it properly:

How It Works

The DataGridCellInfo internally stores an ItemInfo object that tracks the exact index of the row it belongs to. Since this is a non-public property, we’ll use reflection to access it, letting us pull the index in O(1) time instead of the O(n) cost of linear searches.

Step-by-Step Implementation

Create an extension method to make this reusable across your project:

using System;
using System.Reflection;
using System.Windows.Controls;

public static class DataGridCellInfoExtensions
{
    public static int GetRowIndex(this DataGridCellInfo cellInfo)
    {
        // Guard against invalid cell info
        if (!cellInfo.IsValid)
            throw new ArgumentException("The provided DataGridCellInfo is invalid.", nameof(cellInfo));

        // Retrieve the non-public ItemInfo property
        var itemInfoProperty = typeof(DataGridCellInfo).GetProperty(
            "ItemInfo", 
            BindingFlags.NonPublic | BindingFlags.Instance);
        
        if (itemInfoProperty == null)
            throw new InvalidOperationException("Could not access the internal ItemInfo property. This may be due to a WPF version change.");

        var itemInfo = itemInfoProperty.GetValue(cellInfo);
        if (itemInfo == null)
            return -1;

        // Get the Index field from the ItemInfo object
        var indexField = itemInfo.GetType().GetField(
            "Index", 
            BindingFlags.Public | BindingFlags.Instance);
        
        if (indexField == null)
            throw new InvalidOperationException("Could not access the Index field in ItemInfo. This may be due to a WPF version change.");

        return (int)indexField.GetValue(itemInfo);
    }
}

Usage Example

Just call the extension method on any valid DataGridCellInfo:

DataGridCellInfo selectedCell = myDataGrid.SelectedCells[0];
int rowIndex = selectedCell.GetRowIndex();

Important Caveats

Since we’re tapping into internal WPF APIs:

  • Version Compatibility: Microsoft might rename, modify, or remove ItemInfo or the Index field in future .NET/WPF updates. Always test this code when upgrading your framework version.
  • Fallback Plan: For robustness, add a fallback to the linear search method if reflection fails. Here’s how to extend the method:
public static int GetRowIndexSafe(this DataGridCellInfo cellInfo, DataGrid dataGrid)
{
    try
    {
        return cellInfo.GetRowIndex();
    }
    catch (Exception)
    {
        // Fall back to the standard (slower) method if reflection fails
        return dataGrid?.Items.IndexOf(cellInfo.Item) ?? -1;
    }
}

Why This Is Better

  • Performance: Directly accessing the stored index avoids iterating through the entire Items collection, which is a massive win for large DataGrids with hundreds or thousands of rows.
  • Accuracy: Unlike visual tree traversal workarounds, this uses the same index the DataGrid internally tracks, so it’s less prone to errors from virtualization or UI state changes.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:24:15