Переходите по n строкам вверх или вниз в представлении DataGrid в событиях KeyDown или PreviewKeyDown

#c# #datagridview #keyevent

Вопрос:

У меня возникли проблемы с реализацией навигации по кнопкам со стрелками в представлении DataGrid (источник данных не используется). В представлении DataGrid есть 2 разных типа элементов, в большинстве случаев каждый второй элемент относится к первому типу, и наоборот, остальные относятся ко второму типу. Теперь, если кто-то нажимает клавишу Вверх / вниз, я хочу, чтобы представление DataGrid перескочило в строку заданного индекса, а не вверх или вниз.

Как бы я ни пытался решить эту проблему, неясно, когда на самом деле закончится событие. Если я попробую сделать это внутри метода _previewKeyDown:

 if (DgvCarPosAndTrafficMsg.CurrentRow != null)
        {
            if (e.KeyCode == Keys.Down)
            {
                if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Ascending)
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i < SessionItems.Count; i  )
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i > 0; i--)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
            }
            else if (e.KeyCode == Keys.Up)
            {

                if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Descending)
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i < SessionItems.Count; i  )
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i > 0; i--)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
            }
 

он все равно будет просто прыгать вверх или вниз по 1 ряду.
Я понятия не имею, когда это событие на самом деле обрабатывается автоматически, и я хотел бы иметь свое собственное поведение ключевых событий вверх и вниз. Пожалуйста, помогите мне, просмотры данных в C# и их раздражающие события мне очень трудно отследить. Похоже, что каждое событие этих сеток обрабатывается по-разному, для некоторых событий новое состояние уже применено, для других (OnSelectionChanged) оно обрабатывается впоследствии. Это плохо документировано и не интуитивно понятно, я хочу избежать / переопределить все эти фоновые материалы.

Ответ №1:

Хорошо, я нашел решение, используя только один метод события:

Вот мой код, важно установить evenArgs как обработанные, а затем выполнить свой собственный метод обновления сетки:

     private void DgvCarPosAndTrafficMsg_KeyDown(object sender, KeyEventArgs e)
    {
        int diffDown;
        int diffUp;
        if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Descending)
        {

            diffDown = 1;
            diffUp = -2;
        }
        else
        {

            diffDown = 2;
            diffUp = -1;
        }

        if (DgvCarPosAndTrafficMsg.CurrentRow != null)
        {
            if (e.KeyCode == Keys.Down amp;amp; DgvCarPosAndTrafficMsg.CurrentRow.Index < DgvCarPosAndTrafficMsg.Rows.Count - diffDown)
            {

                DgvCarPosAndTrafficMsg.CurrentCell = DgvCarPosAndTrafficMsg.Rows[DgvCarPosAndTrafficMsg.CurrentRow.Index   diffDown].Cells[0];
            }
            else if (e.KeyCode == Keys.Up amp;amp; DgvCarPosAndTrafficMsg.CurrentRow.Index   diffUp > 0)
            {

                DgvCarPosAndTrafficMsg.CurrentCell = DgvCarPosAndTrafficMsg.Rows[DgvCarPosAndTrafficMsg.CurrentRow.Index   diffUp].Cells[0];
            }

        }
        e.Handled = true;
        DgvCarPosAndTrafficMsg_UpdateAll();
    }
 

Я всегда прыгаю вверх/вниз на 2 строки, так как ожидаю, что там будет элемент того же типа, но в моем методе UpdateAll() я снова проверяю, был ли он правильным, и при необходимости исправляю его, иначе (если уже правильно) Я обновляю визуализацию данных (и заполняю другие сетки деталями выбранной записи). Я надеюсь, что это поможет и другим тоже.

У вас может быть -2 и 2 для обоих событий, после этого у меня будет некоторое лечение, поэтому эти значения являются моими необходимыми индексами, отрегулируйте это в соответствии с вашим случаем или укажите конкретный индекс (как видно из вопроса).