Обход ячеек только для чтения в DataGridView при нажатии клавиши TAB - PullRequest
8 голосов
/ 15 апреля 2009

Может кто-нибудь показать мне какой-нибудь код того, как я могу обходить ячейки только для чтения в DatagridView при нажатии клавиши TAB?

Ответы [ 8 ]

13 голосов
/ 24 января 2012
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
{
   if (dataGridView1.CurrentRow.Cells[e.ColumnIndex].ReadOnly)
    {
        SendKeys.Send("{tab}");
    }
}
5 голосов
/ 15 апреля 2009

Переопределение события SelectionChanged - правильный подход. Свойство CurrentCell можно использовать для установки текущей ячейки. Вы хотите что-то вроде этого:

private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
    DataGridViewCell currentCell = dataGridView.CurrentCell;
    if (currentCell != null)
    {
        int nextRow = currentCell.RowIndex;
        int nextCol = currentCell.ColumnIndex + 1;
        if (nextCol == dataGridView.ColumnCount)
        {
            nextCol = 0;
            nextRow++;
        }
        if (nextRow == dataGridView.RowCount)
        {
            nextRow = 0;
        }
        DataGridViewCell nextCell = dataGridView.Rows[nextRow].Cells[nextCol];
        if (nextCell != null && nextCell.Visible)
        {
            dataGridView.CurrentCell = nextCell;
        }
    }
}

Вам потребуется добавить тест для текущей ячейки, доступной только для чтения, и выполнить цикл, пока следующая ячейка невидима или доступна только для чтения. Вам также нужно проверить, чтобы убедиться, что вы не зацикливаетесь, если все ячейки доступны только для чтения.

Вам придется справиться со случаем, когда индекс отображения также отличается от базового индекса.

Чтобы получить такое поведение только при нажатии клавиши Tab, вам нужно добавить обработчик KeyDown:

private void AlbumChecker_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Tab)
    {
        SelectNextEditableCell(DataGridView dataGridView);
    }
}

и поместите первый код в этот новый метод.

Возможно, вы захотите проверить, что DataGridView также имеет фокус.

3 голосов
/ 04 сентября 2010

Я сделал пример, наследующий DataGridView класс. Этот пример работает для клавиш TAB и ENTER, поэтому пользователь может быстро вставить данные, но все же может использовать мышь или клавиши «вверх», «вниз», «вправо» и «влево», чтобы выбрать ячейки и скопировать их в Excel. Он работает, имитируя несколько вкладок, пока Grid не попадет в ячейку, отличную от ReadOnly. Надеюсь, это полезно.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace System.Windows.Forms
{
  class MyDataGridView : DataGridView
  {
    protected override bool ProcessDialogKey(Keys keyData)
    {
      if (keyData == Keys.Enter || keyData == Keys.Tab)
      {
        MyProcessTabKey(Keys.Tab);
        return true;
      }
      return base.ProcessDialogKey(keyData);
    }

    protected override bool ProcessDataGridViewKey(KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
      {
        MyProcessTabKey(Keys.Tab);
        return true;
      }
      return base.ProcessDataGridViewKey(e);
    }

    protected bool MyProcessTabKey(Keys keyData)
    {
      bool retValue = base.ProcessTabKey(Keys.Tab);
      while (this.CurrentCell.ReadOnly)
      {
        retValue = base.ProcessTabKey(Keys.Tab);
      }
      return retValue;
    }
  }
}
0 голосов
/ 20 августа 2014
 if (e.KeyValue == 13)
        {
            e = new KeyEventArgs(Keys.Tab);
        }
0 голосов
/ 03 апреля 2014

Вы можете поймать клавишу Tab по этому коду в ProcessDialogKey

    Dim uKeyCode As Keys = (keyData And Keys.KeyCode)
    Dim uModifiers As Keys = (keyData And Keys.Modifiers)

    (uKeyCode = Keys.Return OrElse uKeyCode = Keys.Tab) AndAlso uModifiers = Keys.Shift

И по этому коду в ProcessDataGridViewKey

    (e.KeyCode = Keys.Return OrElse e.KeyCode = Keys.Tab) AndAlso e.Modifiers = Keys.Shift
0 голосов
/ 28 апреля 2012

Гектор - Я надеюсь, что вы все еще слушаете. Ваше решение - самое элегантное и прямолинейное, которое я видел в обширном поиске. Я столкнулся с предложением переопределить ключевые события, но ваше предложение вызвать base.ProcessTabKey особенно простое и обрабатывает передачу фокуса следующему элементу управления, когда вы достигаете конца dgv. Еще одной вещью, в которой нуждалось ваше решение, была проверка в MyProcessTabKey последней ячейки dgv. Если эта ячейка доступна только для чтения и пользовательские вкладки находятся в предыдущей ячейке, оператор while переходит в бесконечный цикл. Добавление следующего кода в качестве первого оператора в цикле while, похоже, решает проблему, хотя и оставляет последнюю (только для чтения) ячейку «активной» (то есть выглядит так, как будто она выбрана).

    if (this.CurrentCell.RowIndex == this.Rows.Count - 1
                && this.CurrentCell.ColumnIndex == this.Columns.Count - 1)
                { retValue = false; break; } 

У меня есть дополнительный вопрос. Знаете ли вы или кто-либо еще, как заставить этот подход работать с Shift-Tab, поэтому dgv пропускает ячейки только для чтения и в обратном направлении? Поскольку Shift и Tab - это разные ключевые события, я не знаю, как обнаружить Shift-Tab в переопределенных методах ProcessDialogKey и ProcessDataGridViewKey. Благодарю. Стив

0 голосов
/ 10 декабря 2009

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

Private Sub myDvGrid_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles myDvGrid.EditingControlShowing
    Dim c As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl)

    RemoveHandler c.PreviewKeyDown, AddressOf edtctrlOn_PreviewKeyDown
    RemoveHandler c.TextChanged, AddressOf edtctrlOn_TextChanged

    AddHandler c.TextChanged, AddressOf edtctrlOn_TextChanged
    AddHandler c.PreviewKeyDown, AddressOf edtctrlOn_PreviewKeyDown

End Sub

Затем в событии edtctrlOn_PreviewKeyDown вы можете передать аргументы в обработчик события PreviewKeyDown исходного массива данных.

0 голосов
/ 28 апреля 2009

Наследовать DataGridView и переопределять ProcessDialogKey (для клавиши, нажатой во время редактирования) и ProcessDataGridViewKey (для клавиши, нажатой во время редактирования). Когда была нажата вкладка, установите CurrentCell на следующую ячейку, не предназначенную только для чтения.

При желании можно переопределить WndProc для фильтрации щелчков мыши по ячейкам только для чтения. (См. DataGridView.GetColumnDisplayRectangle, чтобы найти столбец, по которому щелкнули).

Хороший источник, чтобы начать с здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...