【问题标题】:KeyDown event in a Form表单中的 KeyDown 事件
【发布时间】:2011-06-10 13:33:10
【问题描述】:

我需要将 Ctrl+Z 组合键关联到自定义表单操作(撤消)。

我处理Me.KeyDown 事件,但每次按键时都没有收到它。也许这取决于我拥有的表单中当前的活动控件。

正如我从this article 读到的,我需要

  Private Sub MyForm_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
    e.Handled = True
  End Sub

但即使是这个事件我也没有收到,但是当有一些控件聚焦时,而不是其他的。

  • 不仅如此,对于文本框,我不能再修改文本了;
  • 不仅如此,对于 TextBoxes,还有一个(Windows?)撤消-重做默认机制,它也应该可以工作。
  • 我应该怎么做才能始终收到表单上的KeyDown 事件?

【问题讨论】:

    标签: .net winforms


    【解决方案1】:

    您可以覆盖ProcessCmdKey 以处理表单级别的按键。

    有关更多详细信息和示例,请参阅此问题: Hotkey (not global) in Windows Forms .NET

    【讨论】:

    • 对于 TextBoxes,有一个(Windows?)Undo-Redo 默认机制,应该也可以。
    【解决方案2】:

    您需要将表单的KeyPreview 属性设置为true,这样您的表单才能接收到表单上所有控件的按键事件。这样一来,无论当前焦点是什么控件,您的快捷方式都应该起作用。这是一个简单的示例,您可以使用它来测试它。创建一个带有几个不同控件的新表单,并像这样修改代码:

    public Form1()
    {
        InitializeComponent();
    
        KeyPreview = true;  // indicates that key events for controls on the form
                            // should be registered with the form
    
        KeyDown += new KeyEventHandler(Form1_KeyDown);
    }
    
    void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Modifiers == Keys.Control)
        {
            switch (e.KeyCode)
            {
                case Keys.A:
                    MessageBox.Show("Ctrl + A was pressed!");
                    break;
                case Keys.C:
                    MessageBox.Show("Ctrl + C was pressed!");
                    break;
                case Keys.V:
                    MessageBox.Show("Ctrl + V was pressed!");
                    break;
            }
        }
    }
    

    输入组合键时无论哪个控件有焦点,都会调用表单的Form1_KeyDown方法处理。

    【讨论】:

    • 对不起,我刚刚意识到你的代码示例是 VB,我给你一个 C# 示例。
    • 对不起,最初我的示例是使用 KeyUp 编写的,然后当我意识到您谈到使用 KeyDown 时我更改了它。
    【解决方案3】:

    如果您的表单有一个菜单,那么您可以创建一个 Undo MenuItem 并将其快捷方式属性设置为所需的组合键。

    【讨论】:

      【解决方案4】:
      1. 在我看来,您想要一个 global hook 来了解按下的键。

      2. 如果按照开始的方式进行操作,则必须处理表单(或每个表单)上每个控件的 keypress/keydown 事件。

      编辑

      如果您将 KeyPress 事件与 e.handled = true 混合使用,这可能会让您到达您想要的位置。设置为 true 应该意味着表单接收所有事件而不是单个控件。如果您随后使用 KeyPress 事件来处理 Ctrl+Z,那么您应该能够在表单上运行您的自定义命令,而不管哪个控件具有焦点(根据文档)。

      【讨论】:

      • 那么问题在于,如果不处理表单上每个控件的 keypress/keydown 事件,我认为您无法做到。
      • PreviewKeyDownKeyDown 之间的区别如何?
      • 最大的区别在于它们发生的时间(KeyDown、KeyPress 然后 KeyUp)并且 KeyPress 事件不是由非字符键引发,而是 KeyDown/KeyUp 由非字符键触发。
      【解决方案5】:
       Private Sub form_Load(sender As Object, e As EventArgs) Handles MyBase.Load
              KeyPreview = True
          End Sub
      

      【讨论】:

      • 你应该为你的答案添加一些解释。
      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2013-10-11
      • 2010-11-20
      • 1970-01-01
      相关资源
      最近更新 更多