【问题标题】:How to prevent command keys from being processed by hosting form when control has focus当控件具有焦点时如何防止命令键被托管表单处理
【发布时间】:2023-04-07 05:06:01
【问题描述】:

我正在寻找一种在控件获得焦点时取消键盘快捷键或命令键(如 F1 或 CTRL+O)击键的方法。如果可能在控制级别上。

想象一下,我有一个托管在表单上的控件(例如简单的文本框)。我为打开 (CTRL+O) 或帮助 (F1) 等命令设置了键盘快捷键。如果控件具有键盘焦点并且我按下了我想要阻止执行快捷命令的命令之一。

我希望有一个解决方案,我可以处理这些击键并防止它们在控件级别而不是在表单级别“冒泡”。

【问题讨论】:

  • 您可以设置/取消设置全局标志并将其用作提前退出事件的条件。但说真的,“编辑控件值”如何改变应用程序的上下文?无论你在那里做什么,这听起来都是错误的......
  • 我正在尝试创建一个终端仿真控件,虽然它具有焦点,但我需要将 F1 发送到远程服务器并禁止打开帮助文件。有意义吗?

标签: c# winforms keyboard-shortcuts


【解决方案1】:

您可以使用 KeyDown 事件:

    void DropDownBox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Down:
            case Keys.Up:
                ShowPopup();
                e.SuppressKeyDown = true; // Don't pass it to the underlying control
                break;
        }
    }

如果这还不够 - 比如覆盖 Tab 或任何其他基本击键,这里是 very good article about keyhandling

【讨论】:

    【解决方案2】:

    我发现的唯一解决方案是在控制级别实现/覆盖 ProcessCmdKey 函数:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData >= Keys.F1 && keyData <= Keys.F24)
        {
            WndProc(ref msg);
            return true;
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
    

    我还需要从我的主窗体中删除所有键盘快捷键,并以相同的方式处理它们。

    【讨论】:

    • 注意:在VB.NET中你需要Return MyBase.ProcessCmdKey(msg, keyData)
    【解决方案3】:

    在 keydown 事件中使用e.SuppressKeyPress = true;:我已将复选框的访问键设置为 ALT + C,它运行良好。

     private void cboViewType_KeyDown(object sender, KeyEventArgs e)
            {
                if ((Control.ModifierKeys & Keys.Control) == Keys.Control || e.KeyCode == Keys.F1 || ((Control.ModifierKeys & Keys.Alt) == Keys.Alt && e.KeyCode == Keys.C))
                {
                    // do whatever you want to do here...
                    MessageBox.Show("key overridden");
                    e.SuppressKeyPress = true;
                }
                //e.Handled = true;   // will not work for overriding the shortcut etc.
            }
    

    参考:Override ShortCut Keys on .NET RichTextBox

    【讨论】:

      【解决方案4】:

      您可以通过在任何可聚焦控件的KeyDown 事件处理程序中设置KeyEventArgs.Handled = true 来停止大多数键盘事件的“冒泡”。 它拦截 ALT-F4 或 F1,但不会拦截系统组合,如 ALT-TAB。

      public partial class Form1 : Form
      {
          public Form1()
          {
              InitializeComponent();
          }
      
          private void textBox1_KeyDown(object sender, KeyEventArgs e)
          {
              e.Handled = true;
          }
      }
      

      【讨论】:

      • 谁投反对票你会解释吗?因为正如我所见,答案正是提问者想知道的。
      • SO 问这个:控件具有键盘焦点,我按下了我想阻止执行快捷命令的命令之一。参考 this 了解 e.handled 和 e.SuppressKeyPress。
      • 设置 Handled = true 不会阻止 KeyPress 发生。所以快捷键会触发相关的命令。
      猜你喜欢
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多