【问题标题】:Capturing ctrl + multiple key downs捕获 ctrl + 多个按键
【发布时间】:2020-10-18 13:41:24
【问题描述】:

有没有一种简单的方法可以在类似于 Visual Studio 的 winforms 应用程序中捕获 ctrl+key1key2 事件,例如ctrl+e, c = 注释掉选中的行?

我目前正在覆盖我的表单OnKeyDown 事件:

protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        if (e.Control && e.KeyCode.ToString() == "N")
        {
            //do something...
        }
    }

【问题讨论】:

标签: c# winforms


【解决方案1】:

评论中的文章可能是针对WPF的,但里面的想法仍然可以使用

构造一个类如

    public class MultiKeyGesture
    {
        private List<Keys> _keys;
        private Keys _modifiers;
        public MultiKeyGesture(IEnumerable<Keys> keys, Keys modifiers)
        {
            _keys = new List<Keys>(keys);
            _modifiers = modifiers;
            if (_keys.Count == 0)
            {
                throw new ArgumentException("At least one key must be specified.", "keys");
            }
        }

        private int currentindex;
        public bool Matches(KeyEventArgs e)
        {
            if (e.Modifiers == _modifiers && _keys[currentindex] == e.KeyCode)
                //at least a partial match
                currentindex++;
            else
                //No Match
                currentindex = 0;
            if (currentindex + 1 > _keys.Count)
            {
                //Matched last key
                currentindex = 0;
                return true;
            }
            return false;
        }
    }

但忽略继承。

使用它

    private MultiKeyGesture Shortcut1 = new MultiKeyGesture(new List<Keys> { Keys.A, Keys.B }, Keys.Control);
    private MultiKeyGesture Shortcut2 = new MultiKeyGesture(new List<Keys> { Keys.C, Keys.D }, Keys.Control);
    private MultiKeyGesture Shortcut3 = new MultiKeyGesture(new List<Keys> { Keys.E, Keys.F }, Keys.Control);

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        if (Shortcut1.Matches(e))
            BackColor = Color.Green;
        if (Shortcut2.Matches(e))
            BackColor = Color.Blue;
        if (Shortcut3.Matches(e))
            BackColor = Color.Red;
    }

【讨论】:

  • 嗨 James - 请让我知道构造函数 MultiKeyGesture 中第二个参数的使用。其实我想实现快捷键CTRL+1+2+1; CTRL+1+2+2; CTRL+1+2+3; CTRL+1+2+4; CTRL+1+2+5 在我的 WinForms 应用程序中。使用 MultiKeyGesture 类后,它可以工作,但如果我不按 CTRL 键,它也可以工作。请建议如何实施。
  • 嗨@BrijeshKumarTripathi,我已经在答案中添加了修饰符的实现。我目前没有时间对此进行测试,所以它们可能是一些小问题
  • 谢谢詹姆斯。我已经测试过了,它按预期工作。赞成。
【解决方案2】:

如果你只有两个键的快捷键,就像 VS 一样,你可以将最后按下的键存储在一个变量中。

private Keys lastKeyPressed = null;

protected override void OnKeyDown(KeyEventArgs e)
{
    base.OnKeyDown(e);
    if(e.Control && lastKeyPressed != null)
    {
        if(lastKeyPressed == Keys.firstKey && e.KeyCode == Keys.secondKey)
        {
        }
        else if (...) // so on and so forth.
    }
    else if(e.Control)
        lastKeyPressed = e.KeyCode;
}

protected override void OnKeyUp(KeyEventsArgs e)
{
    if(!e.Control)
       lastKeyPressed = null;
}

这将执行一个两键快捷方式,并在释放 ctrl 键时将其重置。这只是未经测试的伪代码,但它的概念是在按住 Ctrl 时保存最后按下的键,然后在释放我试图传达的 ctrl 时重置它。

【讨论】:

    【解决方案3】:

    为控制键调用 e.Modifiers,为组合键调用 e.KeyCode。

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
       // For Tow Key Shortcut.
       if (e.Modifiers == Keys.Control && e.KeyCode == Keys.B)
       {}
       
         // For Triple Key Shortcut.
       if (e.Modifiers.ToString() == (Keys.Shift+", "+Keys.Control) && e.KeyCode == Keys.B)
       {} 
    }
    
    // For Form level Key events you must have to set KeyPreview to True;
    public Form1()
    {
        InitializeComponent();
        this.KeyPreview = true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 2013-11-04
      相关资源
      最近更新 更多