C# Отправить нажатие клавиши в DataGridViewCell
У меня есть ячейка DateTimePicker в моем DataGridView. Я хотел бы иметь возможность войти в режим редактирования и сбросить календарь при нажатии кнопки. Я могу сделать первую часть без затруднений, но вторая не работает. Если у меня есть автономный DateTimePicker, вызов SendKeys работает должным образом.
//Select the cell and enter edit mode - works
myDGV.CurrentCell = myDGV[calColumn.Index, e.RowIndex];
myDGV.BeginEdit(true);
//Send an ALt-Down keystroke to drop the calendar - doesn't work
SendKeys.SendWait("%{DOWN}");
После отладки я считаю, что проблема в том, что нажатие клавиши отправляется в DGV, а не в конкретную ячейку, которую я пытаюсь отредактировать. Причина, по-моему, заключается в том, что я поместил код в журнал ключей, полученных событиями сетки KeyPress и KeyDown. Они регистрируют мою стрелку вокруг сетки и ключи, отправленные SendKeys, но не те, когда я редактировал ячейку, набирая ее.
2 ответа
Я недавно вновь обратился к этой проблеме, потому что реализация, предоставленная 0A0D, не всегда хорошо сочеталась с навигацией клавиатуры по сетке (стрелки / табуляция). Время от времени можно было обойти DateTimePicker
и введите текст в DataGridViewTextBoxCell
, Это привело к тому, что моя логика валидации вышла из-под контроля; и после того, как я не смог найти способ предотвратить провал, я решил попытаться заставить колонку работать снова.
Исправление оказалось очень простым. Я создал расширенный DateTimePicker
с методом отправки нажатия клавиши, необходимой для отображения календаря.
/// <summary>
/// Extended DateTimePicker with a method to programmatically display the calendar.
/// </summary>
class DateTimePickerEx : DateTimePicker
{
[DllImport("user32.dll")]
private static extern bool PostMessage(
IntPtr hWnd, // handle to destination window
Int32 msg, // message
Int32 wParam, // first message parameter
Int32 lParam // second message parameter
);
const Int32 WM_LBUTTONDOWN = 0x0201;
/// <summary>
/// Displays the calendar input control.
/// </summary>
public void ShowCalendar()
{
Int32 x = Width - 10;
Int32 y = Height / 2;
Int32 lParam = x + y * 0x00010000;
PostMessage(Handle, WM_LBUTTONDOWN, 1, lParam);
}
}
Затем я изменил пример столбца MSDN DateTime, чтобы CalendarEditingControl
наследовать от DateTimePickerEx
,
Затем в форме размещения DataGridView
Я использовал EditingControl
свойство называть ShowCalendar()
метод.
DateTimePickerEx dtp = myDataGridView.EditingControl as DateTimePickerEx;
if (dtp != null)
dtp.ShowCalendar();
Пожалуйста, смотрите мой ответ на C# Winforms DataGridView Time Column. Я верю, что это будет соответствовать вашим потребностям. Вы также можете использовать его для столбца, который имеет ComboBox.