为什么在IsInputKey设置为true时第二次调用PreviewKeyDown事件?

时间:2012-08-10 14:36:22

标签: c# winforms events

VS2010 C#.Net 4.1

我正在处理用户必须在ComboBox中选择或输入初始数据的表单。使用下面的代码,花了一些时间推断,当用户点击Tab键时,如果数据正确,我启用编辑按钮,否则按钮被禁用,它移动到下一个按钮。

此代码有效,但副作用是当我将PreviewKeyDown设置为true时IsInputKey事件再次出现。这会调用两次验证。 KeyDown事件只调用一次,而IsInputKey在第二次调用时再次为假,因此我需要再次检查验证。

我想了解为什么并可能避免它。

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(); 
  } 
} 

1 个答案:

答案 0 :(得分:5)

为什么?很难回答,Winforms就是这样。首先来自消息循环,再次来自控件的消息调度程序。该事件实际上是一种实现受保护的IsInputKey()方法的替代方法,而不必覆盖控件类。有点黑客,我总是覆盖并且从未使用过该事件。

更好的鼠标陷阱是覆盖ProcessCmdKey()。像这样:

    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);
    }