如何实现像Tab导航一样的WPF Datagrid箭头键导航

时间:2011-01-05 02:16:59

标签: wpf wpfdatagrid arrow-keys

我有一个DataGrid,几乎没有可编辑的单元格。用户可以通过每个单元格选项卡来编辑内容。现在我想实现右箭头键,就像tab一样。因此,当用户完成一个单元格的编辑并按下右箭头键时,焦点将移动到下一个可编辑单元格并开始编辑。

例如,我有关注屏幕:

当用户按右箭头键时,我希望我的数据网格如下:

4 个答案:

答案 0 :(得分:1)

DataGrid实际上自动处理右,左,上,下箭头键。话虽这么说,您可以使用任何这些键移动单元格焦点,然后开始键入以进入编辑模式(如果单元格是可编辑的)。您不必听按键按下事件。请注意,如果您点击“Enter”,那么您将移至下一行。

编辑:

当然,默认情况下,箭头键不会将单元格置于编辑模式。相反,您必须输入内容或使用鼠标指针。但是,您可以执行以下操作:

    private void myDataGrid_CurrentCellChanged(object sender, EventArgs e)
    {
        myDataGrid.BeginEdit();
    }

这将强制焦点上的单元格进入编辑模式。我尝试使用键事件处理程序,但似乎DataGrid不会让用户听到箭头键和Enter(尽管你可以使用WIN32 API)。现在,无论何时使用任何箭头键,新选择的单元格都将处于编辑模式。尝试按Esc以逃避此模式。

答案 1 :(得分:0)

这是我使用箭头键导航的代码

它放在Datagrid_KeyUp事件

    DataGridCell DGcell = new DataGridCell();
    DGcell = GetCell(index, _Header);
    if (DGcell != null)
    {
         CurrentCellContentType = DGcell.Content.GetType().Name.ToString();
    }
    DataGridCell ProdCodeCell = GetCell(index, 0);
    DataGridCell DescCell = GetCell(index, 1);
    DataGridCell CostPriceCell = GetCell(index, 4);
    DataGridCell VatRateCell = GetCell(index, 9);

    DataGridCellInfo PCell = new DataGridCellInfo(ProdCodeCell);
    DataGridCellInfo DCell = new DataGridCellInfo(DescCell);
    DataGridCellInfo PriceCell = new DataGridCellInfo(CostPriceCell);
    DataGridCellInfo VatCell = new DataGridCellInfo(VatRateCell);

    string ProdCellContentType = PCell.Column.GetCellContent(PCell.Item).GetType().Name.ToString();
    string DescCellContentType = DCell.Column.GetCellContent(DCell.Item).GetType().Name.ToString();
    string PriceCellContentType = PriceCell.Column.GetCellContent(PriceCell.Item).GetType().Name.ToString();
    string VatCellContentType = VatCell.Column.GetCellContent(VatCell.Item).GetType().Name.ToString();

    switch (e.Key)
    {
    case Key.Left:
        if (CurrentCellContentType == "TextBlock") e.Handled = false;
        else if (CurrentCellContentType == "TextBox")
        {
            DataGridCellInfo cellLeft = new DataGridCellInfo(GetCell(index, _Header - 1));
            DgInvoiceLines.CurrentCell = cellLeft;
        }
        break;
    case Key.Right:
        if (CurrentCellContentType == "TextBlock") else e.Handled = false;

        else if (CurrentCellContentType == "TextBox")
        {
            DataGridCellInfo cellRight = new DataGridCellInfo(GetCell(index, _Header + 1));
            DgInvoiceLines.CurrentCell = cellRight;
        }
        break;
    case Key.Up:
        if (index != 0)
        {
            if (CurrentCellContentType == "TextBlock") e.Handled = false;
            else if (CurrentCellContentType == "TextBox")
            {
                DataGridCellInfo cellUp = new DataGridCellInfo(GetCell(index - 1, _Header));
                DgInvoiceLines.CurrentCell = cellUp;
                DgInvoiceLines.SelectedItem = DgInvoiceLines.Items[index - 1];
            }
        }
        break;

    case Key.Down:
        if (CurrentCellContentType == "TextBlock") e.Handled = false;
        else if (CurrentCellContentType == "TextBox")
        {
            DataGridCellInfo cellDown = new DataGridCellInfo(GetCell(index + 1, _Header));
            DgInvoiceLines.CurrentCell = cellDown;
            DgInvoiceLines.SelectedItem = DgInvoiceLines.Items[index + 1];
        }
        break;

我使用switch语句为每个列标题分配一个数字

HTH。

答案 2 :(得分:0)

这是我的解决方案,有效。

在构造函数中:

dataGridSubmissionData.KeyUp += DataGridSubmissionDataOnKeyUp;
            dataGridSubmissionData.BeginningEdit += DataGridSubmissionDataOnBeginningEdit;
            dataGridSubmissionData.CellEditEnding += DataGridSubmissionDataOnCellEditEnding;
            dataGridSubmissionData.CurrentCellChanged += DataGridSubmissionDataOnCurrentCellChanged;

在身体课上:

private bool isCellInEditionMode = false;

 private void DataGridSubmissionDataOnCurrentCellChanged(object sender, EventArgs eventArgs)
        {
            dataGridSubmissionData.BeginEdit();
        }

        private void DataGridSubmissionDataOnCellEditEnding(object sender, DataGridCellEditEndingEventArgs dataGridCellEditEndingEventArgs)
        {
            isCellInEditionMode = false;
        }

        private void DataGridSubmissionDataOnBeginningEdit(object sender, DataGridBeginningEditEventArgs dataGridBeginningEditEventArgs)
        {
            isCellInEditionMode = true;
        }

private void DataGridSubmissionDataOnKeyUp(object sender, KeyEventArgs keyEventArgs)
        {
            if (keyEventArgs.Key == Key.Up || keyEventArgs.Key == Key.Down || keyEventArgs.Key == Key.Left || keyEventArgs.Key == Key.Right)
            {
                if (!isCellInEditionMode)
                    return;

                dataGridSubmissionData.CommitEdit();

                var key = keyEventArgs.Key; // Key to send
                var target = dataGridSubmissionData; // Target element
                var routedEvent = Keyboard.KeyDownEvent; // Event to send

                target.RaiseEvent(
                    new KeyEventArgs(
                        Keyboard.PrimaryDevice,
                        PresentationSource.FromVisual(target),
                        0,
                        key) {RoutedEvent = routedEvent}
                    );
            }
        }

我希望我的回答会对某人有所帮助。

答案 3 :(得分:0)

如果您的案例是WPF 托管窗口,则会调用无模式WPF

解决方案可能就是这样:

Window window = new Window();
System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(window);
window.Show();

我见过解决方案here