简体   繁体   English

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

[英]How to Handle Both Short cut Keys and Press and Hold Keys on the Same Control

My WinForms app (targeting NET 3.5) uses keyboard shortcuts that I handle with ProcessCmdKey. 我的WinForms应用程序(针对NET 3.5)使用我通过ProcessCmdKey处理的键盘快捷键。 I also have a small number of keys that are press and hold. 我还按住了几个键。 For example the user presses the R key and drags out an area, or holds down the D key to temporarily display some objects. 例如,用户按下R键并拖出一个区域,或者按住D键以临时显示一些对象。 All this is associated with a Canvas control. 所有这些都与Canvas控件相关联。

I have been handling the press and hold keys via the canvas Key_Down and Key_Up events. 我一直在通过画布的Key_Down和Key_Up事件处理按住键。

I thought all this worked since most of it has been in the code for some time. 我认为所有这些都有效,因为大多数代码已经存在了一段时间。 However it has just become apparent that the press and hold actions are erratic and not guaranteed. 但是,很明显,按住动作是不稳定且不能保证的。

I am aware that ProcessCmdKey gets called before the Key_Down event and I can stop the Key_Down event by returning true from ProcessCmdKey for handled short cuts. 我知道ProcessCmdKey在Key_Down事件之前被调用,并且可以通过从ProcessCmdKey返回true来处理快捷方式来停止Key_Down事件。 As far as I can tell I can't stop the Key_Up event from being triggered though 据我所知,虽然我无法阻止Key_Up事件被触发

The press and hold actions worked sometimes but then stop. 长按动作有时起作用,但随后停止。 The most reliable way to stop then is to press a Modifier Key. 然后,最可靠的停止方法是按修改键。 I had code in the Key_Down and Key_Up events related to the modifier keys which I suspect was responsible. 我在Key_Down和Key_Up事件中有与我怀疑是负责的修改键相关的代码。

As an alternative I tried the code Hans proposed in the answer to this question: ProcessCmdKey - wait for KeyUp? 作为替代方案,我尝试了汉斯在此问题的答案中提出的代码: ProcessCmdKey-等待KeyUp吗? I got it to work and disabled the code in the Key down and up events. 我使它工作并禁用了Key down和up事件中的代码。 This worked but stopped after pressing a modifier key since there was code for them in the Key_Down and Key_Up events. 这可以工作,但是在按下修饰键后便停止了,因为Key_Down和Key_Up事件中有针对它们的代码。 Removing that seems to get it working and I am left with the press and hold keys still failing if I use some other keys such as F8. 删除它似乎可以使它正常工作,并且如果我使用其他一些键(例如F8),则按住键的操作仍然失败。

I have checked a number of other anwers to similar questions: Skipping KeyDown On Override ProcessCmdKey EventHandller and Key Events: ProcessCmdKey . 我已经检查了许多其他类似问题的答案: 在覆盖ProcessCmdKey EventHandller关键事件:ProcessCmdKey时 跳过KeyDown

My ProcessCmdKey code is standard as far as I can tell. 据我所知,我的ProcessCmdKey代码是标准的。 I can offer the code but I am just handling the KeyData in a switch block and acting on the combinations I want. 我可以提供代码,但是我只是在一个switch块中处理KeyData并按照我想要的组合进行操作。

The code for the Key_Down and Key_Up follows this pattern 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);
}

I have tried with both the forms KeyPreview Property set to true and to false. 我尝试将KeyPreview Property两种形式都设置为true和false。 This does not appear to change the behavior. 这似乎没有改变行为。

So in summary I need to handle both keyboard short cuts and press and hold keys at the same time on a single canvas. 因此,总而言之,我需要在一块画布上同时处理两个键盘快捷键并同时按住键。 Overall I have sort of got it working but at the cost of losing the code that shows the user when a modifier key is down and it all seems a bit of a lash-up now. 总的来说,我已经使其工作了,但是是以丢失修改器键按下时向用户显示代码的代价为代价的,这一切现在似乎有些不合时宜。 I am sure there must be a better way but I am running out of ideas so would appreciate some advice. 我相信一定有更好的方法,但是我的想法已经用完了,因此请多多指教。

EDIT 编辑

I have now found that the keys that block the Press and Hold keys are all special in some way or another. 现在,我发现阻止“按住”键的键在某种程度上都是特殊的。 Esc, F1-F2, Home, End, PageUp, PageDown and the arrow keys. Esc,F1-F2,Home,End,PageUp,PageDown和方向键。 Hit one of these to stop the Press and Hold working; 点击其中之一停止“按住”操作; hit one of these to allow it to work. 击中其中之一以使其正常工作。 Any and all of these keys toggle the working of the press and hold. 所有这些键中的任何一个都可以切换按住状态。

I have tried forcing focus onto the canvas but that is not it. 我曾尝试将注意力集中在画布上,但事实并非如此。 I have tried to override IsInputKey but that does not work. 我试图覆盖IsInputKey,但这不起作用。 So I am no further forward other than knowing it is these 'special keys' 因此,除了知道这些“特殊键”之外,我别无所求

I am answering this in embarrassment. 我很尴尬地回答这个问题。 After testing my code on another computer the problem is the keyboard. 在另一台计算机上测试我的代码后,问题出在键盘上。 For reasons that I do not understand the 'special keys' on keyboard on this computer appears responsible for blocking the capturing of press and hold key strokes. 由于某些原因,我无法理解这台计算机键盘上的“特殊键”,这可能导致无法捕获按下并按住的按键。

So far as I can tell the code is fine so there is not a C# or WinForms issue here at all. 据我所知,代码很好,因此这里根本没有C#或WinForms问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM