4

VS2010 C# .Net 4.1

I am working on a form that the user must select or enter initial data in a ComboBox. Using the code below, which took some time to deduce, I enable the Edit button when the user hits the Tab key if the data is correct, otherwise the button is disabled it moves to the next button.

This code works, but a side effect is that the PreviewKeyDown event reoccurs when I set IsInputKey to true. This calls validation twice. The KeyDown event is only called once, and the IsInputKey is false again on the second call so I do need to check validation again.

I'd like to understand why and possibly avoid it.

private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { 
  if (e.KeyData == Keys.Tab) { 
    if (ValidationRoutine()) { 
      e.IsInputKey = true;  //If Validated, signals KeyDown to examine this key 
    } //Side effect - This event is called twice when IsInputKey is set to true 
  }           
} 

private void comboBox1_KeyDown(object sender, KeyEventArgs e) { 
  if (e.KeyData == Keys.Tab) { 
      e.SuppressKeyPress = true; //Stops further processing of the TAB key 
      btnEdit.Enabled = true; 
      btnEdit.Focus(); 
  } 
} 
Rich Shealer
  • 3,362
  • 1
  • 34
  • 59
  • have you tried removing the code in the PreviewKeyDown and adding the code in a different Event Handler.. PreviewKeyDown happens / gets fired before the actual KeyDown Event.. – MethodMan Aug 10 '12 at 14:40
  • @DJ KRAZE-This is were it needs to be to allow the Tab to be surpressed in the KeyDown event. If I don't surpress it the focus moves to the next button in the order because my target button wasn't enabled in time. I can have full validation elsewhere and check a simple flag for this test. But I'd like to know why it's called twice. – Rich Shealer Aug 10 '12 at 14:51

1 Answers1

6

The why? is hard to answer, Winforms just does. First from the message loop, again from the control's message dispatcher. The event was really meant as an alternative way to implement the protected IsInputKey() method without having to override the control class. Bit of a hack, I always override and never used the event.

The better mouse trap is to override ProcessCmdKey() instead. Like this:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (this.ActiveControl == comboBox1 && keyData == Keys.Tab) {
            if (ValidationRoutine()) {
                btnEdit.Enabled = true;
                btnEdit.Focus();
                return true;
            }
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 1
    This even works with AutoComplete turned on. Would you mind posting this answer on my original question: http://stackoverflow.com/questions/11895235 . Thank you! I spent way too many hours on this minor UI feature, but now it will work for anything in the future! – Rich Shealer Aug 10 '12 at 16:13