#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 для обоих событий, после этого у меня будет некоторое лечение, поэтому эти значения являются моими необходимыми индексами, отрегулируйте это в соответствии с вашим случаем или укажите конкретный индекс (как видно из вопроса).