【问题标题】:How to Disable Shortkeys on ComboBox In C# using Windows Application?如何使用 Windows 应用程序在 C# 中禁用 ComboBox 上的快捷键?
【发布时间】:2013-07-10 05:24:32
【问题描述】:

在主窗体中,我有快捷键(ctrl + S)用于将数据保存在数据库中。对于组合框 (ctrl + Alphabets) 是默认操作。如何禁用组合框的快捷键?

更新:

在 keyPress 事件中我们可以这样做

        if (ModifierKeys == Keys.Control)
        {
            e.Handled = true;
        }

【问题讨论】:

标签: c# winforms combobox keyboard-shortcuts


【解决方案1】:

您可以尝试覆盖主窗体的 ProcessCmdKey 方法:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  const int WM_KEYDOWN = 0x100; 

  if (keyData == (Keys.Control | Keys.S)) {
    if (msg.Msg == WM_KEYDOWN)
      MySaveDataToDatabase(); // <- Do your save command

    return true; // <- Stop processing the WM_KeyDown message for Ctrl + S (and shortcut as well)
  }

  // All other key messages process as usual
  return base.ProcessCmdKey(ref msg, keyData);
}

【讨论】:

    【解决方案2】:

    我觉得您的问题实际上是组合框在您的表单之前获得按键。如果您想在控件之前处理按键,请务必将 Form 的 KeyPreview 属性设置为 true。

    有关 KeyPreview 属性的更多信息: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview(v=vs.100).aspx

    如果您遇到覆盖 F4 键(默认情况下在组合框中显示所有可用选项)之类的问题,请注意将表单的 KeyPress 事件处理程序中的 KeyPressEventArgs.Handled 属性设置为 true。

    【讨论】:

      【解决方案3】:

      对于大多数热键,您可以覆盖 PreviewKeyDown 事件,指定允许或不允许的内容,例如:

      void comboBox_PreviewKeyDown(object sender, KeyEventArgs e)
      {
         var keysToIgnore = new []{
             Keys.S,
             Keys.X,
             Keys.F4,
             Keys.Space,
         }.ToList();
      
         if (keysToIgnore.Contains(e.KeyCode)) {
            if(e.Modifiers == Keys.Alt) ; // Do stuff (or don't) here
         }
      }
      

      根据您的实际用例,您可以通过各种方式构建逻辑,但希望您能理解。

      您可能会发现某些热键组合无法通过这种方式禁用,在这种情况下,您需要使用 Win32API:UnregisterHotKey。更多信息在这里:

      http://msdn.microsoft.com/en-us/library/windows/desktop/ms646327%28v=vs.85%29.aspx

      使用 PreviewKeyDown 事件的主要优点是您还可以轻松替换行为,而不仅仅是禁用它。使用 UnregisterHotKey 的主要优点是它在较低级别上运行,并且是一种更强大、更可靠的禁用热键的方法。

      编辑:

      如果您需要获取连续范围的值,您可以尝试以下方法:

      int keyCode = (int) (e.KeyCode);
      if(keyCode >= (int)(Keys.A) && keyCode <= (int)(Keys.Z)) { /* do stuff */ } 
      

      但是,理想的解决方案实际上取决于您的用例的具体情况。没有通用的“正确答案”。

      【讨论】:

      • PreviewKeyDown中没有key属性
      • 谢谢,已修复。应该是KeyCode 而不是Key
      • 那么对于所有字母你怎么能做到这一点。
      • 添加了多个项目的示例。如果您需要所有可能的密钥,则根本不要使用 KeyCode 测试。例如,如果您需要所有字母或数字,则必须在某处将它们全部声明(如上例所示)。没有(干净的)方法。
      猜你喜欢
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      相关资源
      最近更新 更多