C# WPF KeyDown 高亮显示 + 选择数据网格中的最后一行

C# WPF KeyDown highlight + selected last row in datagrid

我正在开发用户可以将产品添加到数据网格的应用程序,其中包含产品名称和价格等简单信息,然后 例如,我想按键盘上的 F4 键,我想专注于数据网格中的最后一项,这意味着 select 它并突出显示该项目!

伙计们,我怎样才能做到这一点,我尝试了一些解决方案,比如为我的数据网格设置 selected 索引等等,但它不起作用

谢谢大家, 干杯

您可以使用 InputBinding 来识别按下的 F4 键。

<Window.InputBindings>
    <KeyBinding Key="F4"
                Command="{Binding SelectLastItemCommand}" />
</Window.InputBindings>

您可以在这里查看如何 select 项目:WPF Binding SelectedItem in DataGrid

你的问题出在哪里?处理按钮事件或突出显示该行?似乎是后者,所以看看这个: https://www.codeproject.com/Tips/773382/Row-Highlighting-in-WPF-Grids

以编程方式突出显示 DataGrid 中的行或单元格比仅设置 SelectedIndexSelectedItem 属性.

要复杂一些

然而,可以 select 并在代码中聚焦一行,并通过访问 DataGrid 控件的可视用户界面元素并调用 UIElement.Focus() 特定 DataGridCell 对象上的方法,如以下博客 post.

中所述

如何以编程方式 select 并在 WPF 的 DataGrid 中聚焦行或单元格: https://blog.magnusmontin.net/2013/11/08/how-to-programmatically-select-and-focus-a-row-or-cell-in-a-datagrid-in-wpf/

这是一个例子:

public partial class MainWindow : Window
{
    public MainWindow
    {
        InitializeComponent();
        this.PreviewKeyDown += (s, e) => 
        {
            if(e.Key == Key.F4)
                SelectRowByIndex(dataGridProducts, dataGridProducts.Items.Count - 1);
        };

        //populate DataGrid etc...
    }

    private static void SelectRowByIndex(DataGrid dataGrid, int rowIndex)
    {
        if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.FullRow))
            throw new ArgumentException("The SelectionUnit of the DataGrid must be set to FullRow.");

        if (rowIndex < 0 || rowIndex > (dataGrid.Items.Count - 1))
            throw new ArgumentException(string.Format("{0} is an invalid row index.", rowIndex));

        dataGrid.SelectedItems.Clear();
        object item = dataGrid.Items[rowIndex];
        dataGrid.SelectedItem = item;

        DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
        if (row == null)
        {
            /* bring the data item (Product object) into view
             * in case it has been virtualized away */
            dataGrid.ScrollIntoView(item);
            row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
        }
        if (row != null)
        {
            DataGridCell cell = GetCell(dataGrid, row, 0);
            if (cell != null)
                cell.Focus();
        }
    }

    private static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
    {
        if (rowContainer != null)
        {
            System.Windows.Controls.Primitives.DataGridCellsPresenter presenter 
                = FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
            if (presenter == null)
            {
                /* if the row has been virtualized away, call its ApplyTemplate() method 
                 * to build its visual tree in order for the DataGridCellsPresenter
                 * and the DataGridCells to be created */
                rowContainer.ApplyTemplate();
                presenter = FindVisualChild<System.Windows.Controls.Primitives.DataGridCellsPresenter>(rowContainer);
            }
            if (presenter != null)
            {
                DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
                if (cell == null)
                {
                    /* bring the column into view
                     * in case it has been virtualized away */
                    dataGrid.ScrollIntoView(rowContainer, dataGrid.Columns[column]);
                    cell = presenter.ItemContainerGenerator.ContainerFromIndex(column) as DataGridCell;
                }
                return cell;
            }
        }
        return null;
    }

    private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is T)
                return (T)child;
            else
            {
                T childOfChild = FindVisualChild<T>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
        }
        return null;
    }
}