【问题标题】:How can I debounce a C# Windows Forms ComboBox.PreviewKeyDown event?如何消除 C# Windows 窗体 ComboBox.PreviewKeyDown 事件的抖动?
【发布时间】:2020-04-16 13:40:17
【问题描述】:

我想消除 Windows 窗体 ComboBox.PreviewKeyDown 事件的抖动,因为它似乎总是触发重复事件。我希望每次击键只发生 1 个事件。

例如:

  1. 创建一个新的 C# Windows 窗体应用程序(我尝试过 .NET 4.6.2 和 4.7.2)

  2. 将 ComboBox 和 TextBox 添加到主窗体

  3. 设置textBox1.Multiline = true;

  4. 添加 comboBox1.PreviewKeyDown 事件处理程序代码以将结果附加到 textBox1.Text

  5. 运行并观察 comboBox1 中的每次击键都会触发 PreviewKeyDown 事件 2 次!

using System.Windows.Forms;

namespace ComboBox_Bounce
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
      // Hookup event here in code, not in the Designer
      this.comboBox1.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.comboBox1_PreviewKeyDown);
    }

    private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
      this.textBox1.Text += "comboBox1_PreviewKeyDown=" + e.KeyCode.ToString() +  + System.Environment.NewLine;
    }
  }
}

平台:Visual Studio 16.5.4、Windows 10 [1809] 所有当前更新。

【问题讨论】:

  • 您是否也在设计器中将comboBox1_PreviewKeyDown 设置为PreviewKeyDown 事件的处理程序?
  • 否:在示例中,唯一处理程序在代码中。我分别尝试了设计器处理程序和 += 代码方式,结果相同。为了清楚起见,我将 += 代码处理程序放在我的问题中。如果我添加 textBox1.PreviewKeyDown 处理程序,则 textBox1 事件每次击键只会正确触发一次。这个问题似乎是 ComboBox 特有的。
  • 我对弹跳行为的问题是:我没有找到文档,所以我不知道它是否足够一致,我可以安全地忽略所有其他 ComboBox.PreviewKeyDown 事件。
  • 来自documentation:“您不应该在 PreviewKeyDown 事件处理程序中放置任何逻辑,除了设置 IsInputKey 属性。相反,您应该将您的逻辑放在 KeyDown 事件处理程序中。”
  • ComboBox 是一个复合控件...有 MessageLoop 和 Dispatcher。你为什么使用这个事件而不是 KeyDown?还是覆盖自定义控件的 WndProc 或 ProcessCmdKey?

标签: c# winforms combobox debounce


【解决方案1】:

Control.PreviewKeyDown 应仅用于测试特定按键,然后将 Control.IsInputKey 设置为 true,如果是这种情况,则应使用 Control.KeyDown 事件处理程序。

Control.PreviewKeyDown Event

【讨论】:

    【解决方案2】:

    上面的实现ChrisBD's answer适用于示例:

    using System.Windows.Forms;
    
    namespace ComboBox_Bounce
    {
      public partial class Form1 : Form
      {
        public Form1()
        {
          InitializeComponent();
          this.comboBox1.PreviewKeyDown += this.comboBox1_PreviewKeyDown;
          this.comboBox1.KeyDown += ComboBox1_KeyDown;
        }
    
        private void ComboBox1_KeyDown(object sender, KeyEventArgs e)
        {
          this.textBox1.Text += "comboBox1_KeyDown=" + e.KeyCode.ToString() + System.Environment.NewLine;
        }
    
        private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
          this.textBox1.Text += "comboBox1_PreviewKeyDown=" + e.KeyCode.ToString() + System.Environment.NewLine;
          e.IsInputKey = true;
        }
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-15
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多