У меня есть этот код в пользовательском классе, полученном из DataGridView:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (char.IsNumber(Convert.ToChar(keyData)) ||
char.IsControl(Convert.ToChar(keyData)) ||
(keyData >= Keys.NumPad0 && keyData <= Keys.NumPad9) ||
(keyData == Keys.Up) ||
(keyData == Keys.Down) ||
(keyData == Keys.Left) ||
(keyData == Keys.Right) ||
(keyData == Keys.Home) ||
(keyData == Keys.PageDown) ||
(keyData == Keys.PageUp) ||
(keyData == Keys.Space) ||
(keyData == Keys.Back) ||
(keyData == Keys.Decimal))
{
return false;
}
return true;
}
Я могу вводить данные (числа и .) и переходить от ячейки к ячейке, но если я нажимаю клавишу «Shift», я получаю «System.OverflowException не было обработано кодом пользователя. Сообщение = Значение было слишком большим или слишком мал для символа. Source=mscorlib StackTrace: at System.Convert.ToChar(значение Int32)..."
Я предполагаю, что это строка, которая вызывает проблему:
char.IsControl(Convert.ToChar(keyData))
... но почему Shift проблематичен и что мне делать, чтобы он игнорировал клавишу Shift (у пользователя нет причин нажимать клавишу Shift в DGV).
ОБНОВИТЬ
Должен признаться, я не совсем понимаю ответ Кетцалькоатля, но я попытался применить его следующим образом:
Keys specials = keyData & Keys.Modifiers;
Keys keycode = keyData & ~Keys.Modifiers;
if (char.IsNumber(Convert.ToChar(keyData)) ||
//char.IsControl(Convert.ToChar(keyData)) ||
//(keyData == specials) || <-- didn't work
//(keyData == keycode) || <-- didn't work
(keyData != specials) ||
(keyData != keycode) ||
. . .
... и все равно получаю ту же ошибку. Как я могу применить предоставленную им информацию для решения проблемы?
ОБНОВЛЕНИЕ 2
Я все еще борюсь с этим.
Я пробовал это:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Keys keycode = keyData & ~Keys.Modifiers;
if (keycode >= Keys.D0 && keycode <= Keys.D9 ||
keycode >= Keys.NumPad0 && keycode <= Keys.NumPad9 ||
(keycode == Keys.Up) ||
(keycode == Keys.Down) ||
(keycode == Keys.Left) ||
(keycode == Keys.Right) ||
(keyData == Keys.Tab) ||
(keycode == Keys.Tab) ||
(keycode == Keys.Home) ||
(keycode == Keys.PageDown) ||
(keycode == Keys.PageUp) ||
(keycode == Keys.Space) ||
(keycode == Keys.Back) ||
(keycode == Keys.Decimal))
{
return false;
}
return true;
}
... и этот подход:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
Keys keycode = keyData & ~Keys.Modifiers;
bool isDigit = keycode >= Keys.D0 && keycode <= Keys.D9 ||
keycode >= Keys.NumPad0 && keycode <= Keys.NumPad9;
bool isControl = (keyData & Keys.Modifiers) != Keys.None;
if (isDigit ||
isControl ||
(keyData == Keys.Up) ||
(keyData == Keys.Down) ||
(keyData == Keys.Left) ||
(keyData == Keys.Right) ||
(keyData == Keys.Tab) ||
(keyData == Keys.Home) ||
(keyData == Keys.PageDown) ||
(keyData == Keys.PageUp) ||
(keyData == Keys.Space) ||
(keyData == Keys.Back) ||
(keyData == Keys.Decimal))
{
return false;
}
return true;
}
Оба они решают, что клавиша Shift вызывает переполнение, но оба они предотвращают ввод десятичной дроби. Я этого не понимаю, поскольку Decimal (предположительно) явно разрешен. Все остальное, что явно проверено, разрешено (Home, PageUp, PageDown и т. д.) - это просто "." персонаж, которому запрещен вход.
ОБНОВЛЕНИЕ 3
Использование второго подхода выше и замена «Keys.Decimal» на «Keys.OemPeriod» работает:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Keys keycode = keyData & ~Keys.Modifiers;
bool isDigit = keycode >= Keys.D0 && keycode <= Keys.D9 ||
keycode >= Keys.NumPad0 && keycode <= Keys.NumPad9;
bool isControl = (keyData & Keys.Modifiers) != Keys.None;
if (isDigit ||
isControl ||
(keyData == Keys.Up) ||
(keyData == Keys.Down) ||
(keyData == Keys.Left) ||
(keyData == Keys.Right) ||
(keyData == Keys.Home) ||
(keyData == Keys.Tab) ||
(keyData == Keys.PageDown) ||
(keyData == Keys.PageUp) ||
(keyData == Keys.Space) ||
(keyData == Keys.Back) ||
(keyData == Keys.OemPeriod))
{
return false;
}
return true;
}