从DataGrid中找到焦点单元格



我需要实现一个WPF DataGrid的"复制值到剪贴板"功能,应该可以通过所有常见的渠道:右键单击上下文菜单项;菜单键上下文菜单项;热键Ctrl + C。数据网格内容来自数据绑定,但由于复制命令是一个仅针对视图的操作,因此它完全在视图层中实现,而不是在视图模型中实现。所以我不使用iccommand,而只使用后面代码中的事件处理程序。

DataGrid的SelectionUnit被设置为FullRow,但是箭头导航键仍然有效,并且可以看到单个单元格的焦点矩形。因此,当选择整行时,可以聚焦单个单元格。对于这个命令,我需要确定聚焦的单元格。

菜单项已经相当复杂了。它的Click事件为我提供了MenuItem实例,从中我可以导航到ContextMenu并进一步导航到DataGrid。就是这样,没有点击单元格。我已经知道如何获得数据网格,一次只有一个是可见的。

我现在需要找出哪个单元格是聚焦的。但我甚至无法获得选定单元格或行甚至所有行的列表。我能找到的所有属性都指向信息的一些片段和DataGrid。行根本不存在。我可以在整个可视树中扫描一些集中的DataGridCell,但这可能不是很有效。

任何想法?

后来我还需要第二个函数"复制选定行到剪贴板",复制所有选定行的所有单元格的值,格式可以粘贴到Excel(制表符分隔行)。

辅助函数:

    /// <summary>
    /// Look for child element
    /// </summary>
    /// <typeparam name="childItem">Child Item</typeparam>
    /// <param name="obj">Dependency Object</param>
    /// <returns>The child or null</returns>
    private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
    {
        if (obj == null)
        {
            return null;
        }
        int childCount = VisualTreeHelper.GetChildrenCount(obj);
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is childItem)
            {
                return (childItem)child;
            }
            else
            {
                childItem childOfChild = this.FindVisualChild<childItem>(child);
                if (childOfChild != null)
                {
                    return childOfChild;
                }
            }
        }
        return null;
    }

加载DataGrid后,可以调用:

    /// <summary>
    /// Get the cell of the datagrid.
    /// </summary>
    /// <param name="dataGrid">The data grid in question</param>
    /// <param name="cellInfo">The cell information for a row of that datagrid</param>
    /// <param name="cellIndex">The row index of the cell to find. </param>
    /// <returns>The cell or null</returns>
    private DataGridCell TryToFindGridCell(DataGrid dataGrid, DataGridCellInfo cellInfo, int cellIndex = -1)
    {
        DataGridRow row;
        DataGridCell result = null;
        if (cellIndex < 0)
        {
            row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(cellInfo.Item);
        }
        else
        {
            row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(cellIndex);
        }
        if (row != null)
        {
            int columnIndex = dataGrid.Columns.IndexOf(cellInfo.Column);
            if (columnIndex > -1)
            {
                DataGridCellsPresenter presenter = this.FindVisualChild<DataGridCellsPresenter>(row);
                if (presenter != null)
                {
                    result = presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex) as DataGridCell;
                }
                else
                {
                    result = null;
                }
            }
        }
        return result;
    }

然后在你得到你的单元格后,只需检查IsFocused属性

相关内容

最新更新