我正在使用 WinForms。我KeyDown
为主窗体的事件创建了一个事件处理程序,从而调用了按钮的Click
事件处理程序。
调用的Click
事件处理程序取决于按下的特定键。如果用户单击按钮而不是使用键,然后随后尝试使用键,则键(例如向下箭头)充当制表符循环,改变表单上每个按钮控件之间的焦点(而不是执行Keydown 处理程序)。
有任何想法吗 ?
我正在使用 WinForms。我KeyDown
为主窗体的事件创建了一个事件处理程序,从而调用了按钮的Click
事件处理程序。
调用的Click
事件处理程序取决于按下的特定键。如果用户单击按钮而不是使用键,然后随后尝试使用键,则键(例如向下箭头)充当制表符循环,改变表单上每个按钮控件之间的焦点(而不是执行Keydown 处理程序)。
有任何想法吗 ?
问题是,按钮在单击时具有焦点,因此后续按键不会被表单本身捕获,而是被按钮捕获。在按钮的单击事件处理程序中,关注表单:
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。
根据 SimpleCoder,我必须重写IsInputKey
Button 类的成员。
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,将控制权转移回主窗体. 从这里开始,如果按下后续键(上、下、左或右),表单将执行相应的处理程序。
使用Control.GetNextControl并将焦点设置为它返回的内容。
查看 KeyPreview 属性。http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
将其设置为true
。
或者,您可能想要覆盖ProcessKeyPreview
表单。