I’ve got this code in a custom class derived from 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;
}
I can enter data (numbers and .), and tab from cell to cell, but if I hit the “Shift” key, I get, “System.OverflowException was unhandled by user code
Message=Value was either too large or too small for a character.
Source=mscorlib
StackTrace:
at System.Convert.ToChar(Int32 value)…”
I assume this is the line that’s causing the problem:
char.IsControl(Convert.ToChar(keyData))
…but why is Shift problematic, and what should I do to get it to disregard the Shift key (there’s no reason for the user to press the Shift key in the DGV).
UPDATE
I must admit I don’t quite understand quetzalcoatl’s answer, but I tried to apply it this way:
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) ||
. . .
…and still get the same error. How can I apply the information he provided to solve the problem?
UPDATE 2
I’m still struggling with this.
I’ve tried this:
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;
}
…and this approach:
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;
}
Both of them solve the Shift key causing an overflow, but both of them prevent a decimal from being entered. I don’t understand that, as Decimal is being (supposedly) explicitly allowed. Everything else explicitly checked for is allowed (Home, PageUp, PageDown, etc.) – it’s just the “.” character that is being barred entry.
UPDATE 3
Using the second approach above and replacing “Keys.Decimal” with “Keys.OemPeriod” works:
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;
}
Do not convert a
Keystochar. This does not work. Test if it is a digit withTest if it is a control key with