0

在一个表单上,我有一个带有一些按钮的面板。单击 button1 时,我将面板替换为具有标签(例如this.Controls.Clear()this.Controls.Add(UserControl1))的新 UserControl。除了我的 userControl 上的标签有一个 KeyDown 处理程序。它工作正常,事件触发,但不适用于向上、向下、向左和向右键。谁能解释为什么这些键之间有区别?是什么决定了事件是否被触发?

4

4 回答 4

6

两个基本原因。首先是神秘的:Label 控件无法接收焦点,因此看不到击键。其 KeyDown 事件隐藏在设计器中的原因。不太清楚为什么你会看到任何击键。更常见的原因是光标和 TAB 键用于导航,将焦点从一个控件移动到另一个控件。这是将密钥传递给控件之前完成的。您必须重写该控件,以便您可以重写其 IsInputKey() 方法。但更实际的是,您将覆盖 UserControl 的 ProcessCmdKey() 来解决这两个问题。

Also note that you've got a nasty handle leak in your program. Never call Controls.Clear() without also calling the Dispose() method on the controls you remove. Unless you intended to reuse them later, not so common. It is a nasty kind of leak that the garbage collector doesn't solve and ultimately crashes your program after first making it slow and unwieldy.

于 2012-08-01T08:24:39.203 回答
1

根据MSDN

此事件支持 .NET Framework 基础结构,不打算直接从您的代码中使用

当标签具有焦点时用户按下一个键时发生。

编辑:似乎没有替代事件。根据我的阅读,箭头键绝对应该被检测到。请提供一些代码。

于 2012-08-01T07:58:00.603 回答
1

您应该改写 ProcessCmdKey 方法。箭头键的处理方式与其他标准键不同。另一种解决方案是: Microsoft 建议的http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx

于 2012-08-01T08:04:08.143 回答
0

要处理箭头键,您可以将 Form 的 KeyPreview 属性设置为 true,然后在表单级别而不是特定控件级别处理它们。我已经这样做了,而且效果很好!

如果上述方法对您不起作用,请考虑ProcessCmdKey以下内容:

 protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) 
{

       if(KeyData == Keys.Right)
       {
        //Move Right
         return true;
         }
        else
        {
         return base.ProcessCmdKey(msg, keyData);
        }

 }
于 2012-08-01T08:15:53.213 回答