0

I want to only allow the user to enter 0..9, "." and backspace in my DGV. I thought the KeyDown event might be the ticket, with something like this:

private void dataGridViewPlatypi_KeyDown(object sender, KeyEventArgs args)
{
    args.Handled = !args.KeyCode.Equals(Keys.Decimal); // etc. - add other allowed vals
    if (args.Handled)
    {
        args.SuppressKeyPress = true;
    }
}

...but that doesn't work/has no effect.

I researched and found this: DataGridView keydown event not working in C#

...which led me to creating a custom DGV class with this:

protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
    if ((!keyData.Equals(Keys.Decimal)) &&
        (!keyData.Equals(Keys.???))) // etc.
    {
        //suppress the key somehow
    }
    return base.ProcessCmdKey(msg, keyData); // <-- should this be in an "else" block?
}

...but as you can tell from the "???" and the "somehow" comment, I don't know how to test for the other keys I want to allow (0..9 and backspace)

UPDATE

With able assistance from two respondents, it's now working just great:

I started off with Hans Passant's code here to create a custom DGV-derived control to solve the moveable final row problem:

removing the empty gray space in datagrid in c#

...and then added code based on LarsTech's to filter out unwanted entries in the DGV.

To be precise, this is the exact logic I used to override ProcessCmdKey():

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.Space) ||
        (keyData == Keys.Back) ||
        (keyData == Keys.Decimal))
    {
        return false;
    }
    return true;
}
Community
  • 1
  • 1
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • Sometimes when I go to ask a question on SO, my last question, although already posted, still exists on the "new question" page. Additionally, it is very common for me to get a "compatibility error" web site "crash" (it doesn't really crash, but the msg says that the page had to be reloaded). I'm using IE8. – B. Clay Shannon-B. Crow Raven Sep 26 '12 at 16:18
  • Click on the Meta link at the top of the page to ask or review questions concerning the Stack Overflow website operation. – LarsTech Sep 26 '12 at 16:26
  • The (then, at least), "DataGridView Program Manager" Mark Rideout said here: http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/dc6d4d47-dbb1-42d5-954e-16c5645c89bb/ "you do have to derive from the DataGridView to do what you want. This is due to the way that keyboard handling works for contained controls. In a future version of the DataGridView we would like to add a few more events (yeah!) to help make this scenario easier to do." That post is dated 2005! Surely ("stop calling me Shirley!") there's a better way by now...? – B. Clay Shannon-B. Crow Raven Sep 26 '12 at 16:35
  • Thanks, LarsTech, I never gave that "Meta" business much thought as to what it was/for; I posted a dual-headed question there. – B. Clay Shannon-B. Crow Raven Sep 26 '12 at 16:45

1 Answers1

1

Handling the keys of a text input control is almost never 100%. You might want to investigate using a MaskedTextBox control in the DataGridView in this Code Project.

For the override, this code will get you close:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (
    (keyData >= Keys.D0 && keyData <= Keys.D9) ||
    (keyData >= Keys.NumPad0 && keyData <= Keys.NumPad9) ||
    (keyData == Keys.Decimal | keyData == Keys.OemPeriod) ||
    (keyData == Keys.Back | keyData == Keys.Delete) ||
    (keyData == Keys.Left | keyData == Keys.Up | keyData == Keys.Right | keyData == Keys.Down) ||
    (keyData == Keys.Tab | keyData == Keys.Home | keyData == Keys.End | keyData == Keys.Enter)
    ) {
    return false;
  }

  return true;
}
LarsTech
  • 80,625
  • 14
  • 153
  • 225
  • I want to try this out, but first: is this logic backwards? It seems as if it's rejecting numbers and decimal, when that is what I want to accept (along with space and backspace). – B. Clay Shannon-B. Crow Raven Sep 26 '12 at 17:32
  • @ClayShannon [From the horse's mouth](http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey.aspx): When overriding the ProcessCmdKey method in a derived class, a control should return true to indicate that it has processed the key. For keys that are not processed by the control, the result of calling the base class's ProcessCmdKey method should be returned. – LarsTech Sep 26 '12 at 17:39
  • @ClayShannon I updated the code. The original post would error if you pressed Ctrl-Something. – LarsTech Sep 26 '12 at 18:52