如何在同一控件上同时处理快捷键和按住键

本文关键字:快捷键 处理 控件 | 更新日期: 2023-09-27 17:58:21

我的WinForms应用程序(针对NET 3.5)使用我用ProcessCmdKey处理的键盘快捷键。我还有一些按键可以按住。例如,用户按下R键并拖出一个区域,或者按住D键以临时显示一些对象。所有这些都与Canvas控件相关联。

我一直在通过画布Key_Down和Key_Up事件处理按键。

我认为所有这些都有效,因为大部分已经在代码中存在了一段时间。然而,很明显,施压和扣留的行动是不稳定的,不能保证。

我知道ProcessCmdKey在Key_Down事件之前被调用,我可以通过从ProcessCmdKey返回true来停止Key_Downs事件,以处理捷径。据我所知,我无法阻止Key_Up事件通过触发

按住动作有时奏效,但后来停止了。最可靠的停止方法是按下修改键。我在Key_Down和Key_Up事件中有与修饰符键相关的代码,我怀疑这是罪魁祸首。

作为替代方案,我尝试了Hans在回答这个问题时提出的代码:ProcessCmdKey-等待KeyUp?我让它工作起来,并禁用了Key down和up事件中的代码。这是有效的,但在按下修改键后停止,因为key_Down和key_Up事件中有相应的代码。删除它似乎可以让它工作,如果我使用其他一些键(如F8),按住键仍然会失败。

我已经检查了许多其他类似问题的答案:跳过KeyDown On Override ProcessCmdKey EventHandller和Key Events:ProcessCmdKey。

据我所知,我的ProcessCmdKey代码是标准的。我可以提供代码,但我只是在开关块中处理KeyData,并根据我想要的组合进行操作。

Key_Down和Key_Up的代码遵循以下模式

private void OnPCanvasKeyDown(object sender, KeyEventArgs e)
{
    if (e.Modifiers == Keys.Control)
    {
        controlDown = true;
        ctrlLabel.Text = "CTRL";
    }
    if (e.KeyCode == Keys.D)
    {
       if (!hiddenObjectsVisible)
       {
            hiddenObjectsVisible = true;
            services.ShowCustomHideObjects();
       }
     }
     OnKeyDown(e);
}
private void OnPCanvasKeyUp(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.ControlKey)
  {
      controlDown = false;
      ctrlLabel.Text = string.Empty;
  }
  if (e.KeyCode == Keys.D)
  {
      hiddenObjectsVisible = false;
      services.HideCustomHideObjects();
  }
   OnKeyUp(e);
}

我已经尝试过将窗体KeyPreview属性设置为true和false。这似乎不会改变行为。

总之,我需要在一个画布上同时处理键盘快捷键和按住键。总的来说,我已经让它工作了,但代价是丢失了当修改键按下时向用户显示的代码,现在一切似乎都有点混乱。我相信肯定有更好的方法,但我的想法已经不多了,所以希望能给我一些建议。

编辑

我现在发现,阻止按住键的键在某种程度上都很特别。Esc、F1-F2、Home、End、PageUp、PageDown和箭头键。按下其中一个按钮可停止Press and Hold工作;点击其中一个以使其工作。这些键中的任何一个都可以切换按住操作。

我试过将焦点强制放到画布上,但不是这样。我试过覆盖IsInputKey,但这不起作用。所以我只知道是这些"特殊密钥"

如何在同一控件上同时处理快捷键和按住键

我尴尬地回答了这个问题。在另一台计算机上测试我的代码后,问题出在键盘上。由于我不理解的原因,这台电脑键盘上的"特殊键"似乎是阻止捕捉按住键笔划的原因。

据我所知,代码很好,所以这里根本没有C#或WinForms问题。