【问题标题】:Move to the next column when pressing Enter key in WPF DataGrid在 WPF DataGrid 中按 Enter 键时移动到下一列
【发布时间】:2016-08-03 08:56:29
【问题描述】:

DataGrid 的默认行为是按下Enter 键时向下移动。我正在尝试将其更改为Right

我见过this 并尝试如下实现它。它有点工作,当按下Enter 键时它向右移动一列,但它也在向下移动一行!

例如,当我在包含 55 的单元格上并按 Enter 键时,我最终会在包含 20 的单元格上。

我已经调试过了,但似乎没有找到问题所在。 cell.Focus(); 中单元格的值是正确的,我不知道之后会发生什么。奇怪的是,当我在最后一行并按 Enter 时它起作用了。

------------------
| Depth |  Width | 
------------------
|  55  |   30    |
------------------
|  45  |   20    |
------------------

private void PreviewKeyDown(object sender, KeyEventArgs e)
{
    var grid = (DataGrid)sender;

    if (e.Key == Key.Enter || e.Key == Key.Return)
    {
        var columnIndex = grid.Columns.IndexOf(MyDataGrid.CurrentColumn);

        var rowIndex = grid.Items.IndexOf(MyDataGrid.CurrentItem);

        // index of the next column
        columnIndex = columnIndex + 1;

        // reset column index if we are at the end of the row
        if (columnIndex > grid.Columns.Count - 1)
        {
            rowIndex = rowIndex + 1;
            columnIndex = 0;

            // return if we have reached the last row
            if (rowIndex > grid.Items.Count - 1)
            {
                return;
            }
        }

        // there should always be a selected cell
        if (grid.SelectedCells.Count != 0)
        {
            SelectCellByIndex(grid, rowIndex, columnIndex);
        }
    }
}

public static void SelectCellByIndex(DataGrid dataGrid, int rowIndex, int columnIndex)
{
    if (!dataGrid.SelectionUnit.Equals(DataGridSelectionUnit.CellOrRowHeader))
        throw new ArgumentException("The SelectionUnit of the DataGrid must be set to Cell.");

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

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

    dataGrid.SelectedCells.Clear();

    object item = dataGrid.Items[rowIndex]; //=Product X
    DataGridRow row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
    if (row == null)
    {
        dataGrid.ScrollIntoView(item);
        row = dataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
    }
    if (row != null)
    {
        DataGridCell cell = GetCell(dataGrid, row, columnIndex);
        if (cell != null)
        {
            DataGridCellInfo dataGridCellInfo = new DataGridCellInfo(cell);
            dataGrid.SelectedCells.Add(dataGridCellInfo);
            cell.Focus();
        }
    }
}

public static DataGridCell GetCell(DataGrid dataGrid, DataGridRow rowContainer, int column)
{
    if (rowContainer != null)
    {
        DataGridCellsPresenter presenter = FindVisualChild<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<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;
}

public 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;
}

【问题讨论】:

    标签: c# wpf datagrid wpfdatagrid


    【解决方案1】:

    原因可能是因为一旦你完成了,事件就会继续按照正常流程进行,并且在某个地方完成了。

    你要做的是在你的方法结束时,在你处理完之后,将handled设置为true

     // do your stuff
     e.Handled = true;
     // return here, and it should not go down as well
    

    【讨论】:

    • 哇!我怀疑它与它运行了几次有关,但我不知道如何处理它!非常感谢!
    • 没问题,伙计。很高兴它有帮助:)
    猜你喜欢
    • 2016-01-22
    • 2012-05-11
    • 2012-01-02
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多