简体   繁体   English

基本WinForm KeyDown事件处理

[英]Basic WinForm KeyDown event handling

I'm using WinForms. 我正在使用WinForms。 I've created an event handler for the KeyDown event of the main form, thereby invoking a button's Click event handler. 我已经为主窗体的KeyDown事件创建了一个事件处理程序,从而调用了按钮的Click事件处理程序。

The Click event handler called is dependent upon the specific key pressed. 调用的Click事件处理程序取决于所按下的特定键。 If a user clicks the button rather than using the key, and then subsequently tries to use the key thereafter, the key (down arrow for example) acts as a tab-cycle, changing focus between each button control on the form (rather than executing the Keydown handler). 如果用户单击按钮而不是使用键,然后用户随后尝试使用该键,则该键(例如,向下箭头)将作为一个Tab循环,从而改变表单上每个按钮控件之间的焦点(而不是执行Keydown处理程序)。

Any ideas ? 有任何想法吗 ?

The problem is, the button has the focus when it is clicked, so subsequent key presses are not caught by the form itself, but by the buttons instead. 问题是,单击按钮时按钮具有焦点,因此后续的按键输入不是被窗体本身捕获,而是由按钮捕获。 In the click event handler for the buttons, focus the form: 在按钮的click事件处理程序中,聚焦表单:

this.Focus();

That way, focus is restored to the form so the form will listen for the keypress events. 这样,焦点将恢复到表单,以便表单将侦听按键事件。

Edit 编辑

The real problem, as you have discovered, is that arrow keys are not treated as input keys. 正如您所发现的,真正的问题是箭头键未被视为输入键。 To fix this, you need to create a new class that inherits whatever control you want to use. 要解决此问题,您需要创建一个新类,该类继承要使用的任何控件。 Then, you override the IsInputKey method to treat arrow keys as input keys. 然后,您重写IsInputKey方法将箭头键视为输入键。 Check this link: http://bytes.com/topic/c-sharp/answers/517530-trapping-arrow-keys-usercontrol . 检查此链接: http : //bytes.com/topic/c-sharp/answers/517530-trapping-arrow-keys-usercontrol This article is also useful: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.isinputkey.aspx . 本文也很有用: http : //msdn.microsoft.com/zh-cn/library/system.windows.forms.control.isinputkey.aspx

As per SimpleCoder, I had to override the IsInputKey member for the Button class. 根据SimpleCoder,我必须重写Button类的IsInputKey成员。

public class ControlButton : Button
{
    protected override bool IsInputKey(Keys keyData)
    {
        if (keyData == Keys.Up)
        {
            return true;
        }
        else if (keyData == Keys.Down)
        {
            return true;
        }
        else if (keyData == Keys.Left)
        {
            return true;
        }
        else if (keyData == Keys.Right)
        {
            return true;
        }
        else
        {
            return base.IsInputKey(keyData);
        }
    }
}

Then I needed to instantiate my button objects (in the designer class) using this new class, like so: 然后,我需要使用这个新类实例化我的按钮对象(在Designer类中),如下所示:

    private ControlButton btnDown;
    private ControlButton btnRight;
    private ControlButton btnLeft;
    private ControlButton btnUp;

    this.btnDown = new ControlButton();
    this.btnRight = new ControlButton();
    this.btnUp = new ControlButton();
    this.btnLeft = new ControlButton();

Next I registered OnClick handlers for each of the new button objects like so: 接下来,我为每个新按钮对象注册了OnClick处理程序,如下所示:

    this.btnUp.Click += new System.EventHandler(this.btnUp_Click);

    private void btnUp_Click(object sender, EventArgs e)
    {            
        MessageBox.Show("Up");
    }

(etc.) (等等。)

And registered a KeyDown handler for the main form: 并为主要形式注册了一个KeyDown处理程序:

    this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.frmUavController_KeyDown);

    private void frmUavController_KeyDown(object sender, KeyEventArgs e)
    {
        if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.W))
        {
            btnUp.PerformClick();
        }
        else if ((e.KeyCode == Keys.Down) || (e.KeyCode == Keys.S))
        {
            btnDown.PerformClick();
        }
        else if ((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.A))
        {
            btnLeft.PerformClick();
        }
        else if ((e.KeyCode == Keys.Right) || (e.KeyCode == Keys.D))
        {
            btnRight.PerformClick();
        }
    }

Having set the main form property KeyPreview to true, and seeing as though I had overridden the default behaviour of the Up, Down, Left and Right keys, the button controls no longer cycle focus, but rather return true, transferring control back to the main form. 将主窗体属性KeyPreview为true后,好像我已经覆盖了Up,Down,Left和Right键的默认行为,该按钮不再控制循环焦点,而是返回true,将控制权转移回主菜单。形成。 From here, if subsequent keys (up, down, left or right) are pressed, the form actions the appropriate handler. 从此处开始,如果按下了后续键(上,下,左或右),则表单将操作相应的处理程序。

使用Control.GetNextControl并将Focus设置为其返回的内容。

Look at KeyPreview property. 查看KeyPreview属性。 http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

Set it to true . 将其设置为true

Or alternatively you may want to override ProcessKeyPreview of the form. 或者,您可能想要覆盖ProcessKeyPreview

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

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