我在派生自 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 未被用户代码处理 Message=Value 太大或太小一个字符。Source=mscorlib StackTrace: at System.Convert.ToChar(Int32 value)..."
我认为这是导致问题的行:
char.IsControl(Convert.ToChar(keyData))
...但是为什么 Shift 有问题,我应该怎么做才能让它忽略 Shift 键(用户没有理由按下 DGV 中的 Shift 键)。
更新
我必须承认我不太理解 quetzalcoatl 的回答,但我试图以这种方式应用它:
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;
}