Как реализовать навигацию клавиш со стрелками WPF Datagrid, например, навигацию по вкладкам - PullRequest
1 голос
/ 05 января 2011

У меня есть DataGrid с несколькими редактируемыми ячейками.Пользователи могут перемещаться по каждой ячейке для редактирования содержимого.Теперь я хочу реализовать правую клавишу со стрелкой, работающую так же, как вкладка.Поэтому, когда пользователь заканчивает редактирование одной ячейки и нажимает клавишу со стрелкой вправо, фокус перемещается к следующей редактируемой ячейке и начинает редактирование.

Например, у меня есть следующий экран:

Когда пользователь нажимает клавишу со стрелкой вправо, я хочу, чтобы моя таблица данных была такой:

Ответы [ 4 ]

1 голос
/ 05 января 2011

DataGrid автоматически обрабатывает клавиши со стрелками вправо, влево, вверх, вниз.При этом вы можете перемещать фокус ячейки с помощью любой из этих клавиш, а затем начать печатать, чтобы войти в режим редактирования (если ячейка редактируема).Вам не нужно слушать события нажатия клавиш.Обратите внимание, что если вы нажмете «Enter», то вы перейдете к следующему ряду.

РЕДАКТИРОВАНИЕ:

Конечно, по умолчанию клавиши со стрелками не переводят ячейку в режим редактирования.Вместо этого вы должны ввести вещи или использовать указатель мыши.Но вы можете сделать следующее:

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

Это заставит ячейку, находящуюся в фокусе, войти в режим редактирования.Я пытался использовать ключевые обработчики событий, но кажется, что DataGrid не позволит пользователю слушать клавиши со стрелками и Enter (хотя вы могли бы, если бы вы использовали WIN32 API).Теперь, когда вы используете любую из клавиш со стрелками, вновь выбранная ячейка будет в режиме редактирования.Попробуйте нажать Esc, чтобы выйти из этого режима.

0 голосов
/ 10 июля 2013

Если ваш случай WPF размещенное окно , оно называется немодальный WPF .

И решение может быть таким:

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

Я видел решение здесь

0 голосов
/ 28 мая 2012

это мое решение, которое работает.

В конструкторе:

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

Я надеюсь, что мой ответ кому-нибудь поможет.

0 голосов
/ 30 сентября 2011

Это код, который я использую для навигации с помощью клавиш со стрелками

Он размещен внутри события 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.

...