如何在C#中使用多个修饰键

28

我正在使用 keydown 事件来检测按下的键,并有多个键组合用于不同的操作。

if (e.KeyCode == Keys.C && e.Modifiers == Keys.Control && e.Modifiers == Keys.Shift)
{
    //Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
    //Paste
}

不知什么原因,我按下 Ctrl + Shift + C 组合键时,它不起作用。我已经重新排列过它们,并将其放在顶部,以为可能是由于 Ctrl + C 的干扰,甚至删除了 Ctrl + C 以查看是否存在问题。但它仍然不起作用。我知道可能是非常简单的事情,但却无法理解是什么原因。只要我添加第二个修饰键,所有 "1 个修饰键 + 1 个按键" 的组合都能正常工作。

9个回答

48
if (e.KeyCode == Keys.C && e.Modifiers == (Keys.Control | Keys.Shift))
{
    //Do work
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
    //Paste
}

我使用了完全相同的代码,按住Ctrl和Shift键,但是if语句从未被执行。在实际执行中,我可能做错了什么吗? - A.bakker
@A.bakker,这是已验证有效的真实代码。为了调试你的情况,我建议创建一个 if (e.KeyCode == Keys.C) { 条件,并在那里设置断点。一旦达到断点,检查 e.Modifiers 的值,并相应地调整你的代码。 - Rom

9

你尝试过使用 e.Modifiers == (Keys.Control | Keys.Shift) 吗?


6

如果您想允许使用CtrlShift,则需要使用按位或(因为Keys是一个Flags枚举)

if (e.KeyCode == Keys.C && e.Modifiers == (Keys.Control | Keys.Shift))
{
    //Do work (if Ctrl-Shift-C is pressed, but not if Alt is pressed as well)
}
else if (e.KeyCode == Keys.V && e.Modifiers == Keys.Control)
{
    //Paste (if Ctrl is only modifier pressed)
}

如果同时按下Alt键,则此操作将失败。


2
      if ((Keyboard.Modifiers & ModifierKeys.Shift | ModifierKeys.Control) > 0)
          Debugger.Launch();

2

另一种方法是添加一个不可见的菜单项,将 Ctrl + Shift + C 快捷键分配给它,并在那里处理事件。


1
这是我为 Ctrl+Z 撤销和 Ctrl+Shift+Z 重做操作所做的工作,并且它有效。
  Private Sub Form_Main_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    Select Case e.KeyCode
      Case Keys.Add
        diagramView.ZoomIn()
      Case Keys.Subtract
        diagramView.ZoomOut()
      Case Keys.Z
        If e.Modifiers = Keys.Control + Keys.Shift Then
          diagram.UndoManager.Redo()
        ElseIf e.Modifiers = Keys.Control Then
          diagram.UndoManager.Undo()
        End If
    End Select
  End Sub

这个问题有一个C#标签。但这不是C#代码。 - Preza8

0

试试这个。它应该按照你想要的方式运行,并且更简单。

 if (e.Control)
 {
    if (e.Shift && e.KeyCode == Keys.C)
    {
       //Do work
    }
    else if (e.KeyCode == Keys.V)
    {
       //Paste
    }
 }

0

既然没有人提到它们,我就建议使用KeyEventArgs.KeyData:

if (e.KeyData == (Keys.C | Keys.Control | Keys.Shift)
{
  //do stuff
  //potentially use e.Handled = true
}
if (e.KeyData == (Keys.V | Keys.Control)
{
  //do other stuff
  //potentially use e.Handled = true
}

这应该只对特定的键组合起作用,尽管修饰符的顺序似乎并不重要,但第一个修饰符始终是最后按下的键。

而且 e.Handled = true 应该可以停止它,尽管我不知道具体的机制。


0

如果你有更多的情况需要处理,而且想要更易读的方法,另一种更适合的方法是:

private void Form_KeyDown(object sender, KeyEventArgs e)
{
    Action action = e.KeyData switch
    {
      (Keys.Control | Keys.Shift | Keys.C) => DoWork,
      (Keys.Control | Keys.V) => Paste,
      _ => null
    };
    action?.Invoke();
}
private void DoWork() 
{ // do work }
private void Paste() 
{ // paste }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接