2

我正在使用 WinForms。我KeyDown为主窗体的事件创建了一个事件处理程序,从而调用了按钮的Click事件处理程序。

调用的Click事件处理程序取决于按下的特定键。如果用户单击按钮而不是使用键,然后随后尝试使用键,则键(例如向下箭头)充当制表符循环,改变表单上每个按钮控件之间的焦点(而不是执行Keydown 处理程序)。

有任何想法吗 ?

4

4 回答 4

2

问题是,按钮在单击时具有焦点,因此后续按键不会被表单本身捕获,而是被按钮捕获。在按钮的单击事件处理程序中,关注表单:

this.Focus();

这样,焦点将恢复到表单,因此表单将侦听按键事件。

编辑

正如您所发现的,真正的问题是箭头键不被视为输入键。要解决此问题,您需要创建一个新类来继承您要使用的任何控件。然后,您重写该IsInputKey方法以将箭头键视为输入键。检查此链接:http ://bytes.com/topic/c-sharp/answers/517530-trapping-arrow-keys-usercontrol 。这篇文章也很有用:http: //msdn.microsoft.com/en-us/library/system.windows.forms.control.isinputkey.aspx

于 2010-12-02T02:02:11.760 回答
2

根据 SimpleCoder,我必须重写IsInputKeyButton 类的成员。

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);
        }
    }
}

然后我需要使用这个新类来实例化我的按钮对象(在设计器类中),如下所示:

    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();

接下来,我OnClick为每个新按钮对象注册了处理程序,如下所示:

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

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

(ETC。)

并为主窗体注册了一个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();
        }
    }

将主窗体属性设置KeyPreview为 true,并看到好像我已经覆盖了向上、向下、向左和向右键的默认行为,按钮控件不再循环焦点,而是返回 true,将控制权转移回主窗体. 从这里开始,如果按下后续键(上、下、左或右),表单将执行相应的处理程序。

于 2010-12-02T03:17:03.013 回答
0

使用Control.GetNextControl并将焦点设置为它返回的内容。

于 2010-11-23T06:47:49.183 回答
0

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

将其设置为true

或者,您可能想要覆盖ProcessKeyPreview表单。

于 2010-11-23T06:58:53.047 回答