小组没有得到重点

我正在继续在我简单的graphics程序(使用C#)中编程某种键盘导航。 我又一次遇到了麻烦。

替代文字

我的问题是,我想处理键盘input移动一层。 用鼠标移动图层已经工作得很好,但是控件没有得到焦点( KeyUp / KeyDown / KeyPress和GotFocus / LostFocus都没有为这个控件触发 )。 由于我的类派生自面板(并覆盖了几个事件),我也覆盖了上面提到的事件,但我无法成功地触发这些事件。

我想我可以设法使用Keyboard.GetState()或ProcessCmdWnd之类的东西来实现键盘响应。 但是:我仍然必须能够知道控制何时得到了重点。

有没有或多或less的优雅的方式来添加此function的用户控件(这是基于面板)?

我在这里检查了很multithreading,我可能会使用这种方法来进行键盘input。 焦点问题仍然存在。

提前感谢您的信息!

伊戈尔。

PS:我使用VS2008在C#.NET v3.5中进行编程。 这是一个Windows.Forms应用程序, 而不是WPF

面板类被devise为容器,它避免了重点,所以一个孩子控制总是会得到它。 你需要一些手术来解决这个问题。 我扔了代码来获取KeyDown事件中的光标键击:

using System; using System.Drawing; using System.Windows.Forms; class SelectablePanel : Panel { public SelectablePanel() { this.SetStyle(ControlStyles.Selectable, true); this.TabStop = true; } protected override void OnMouseDown(MouseEventArgs e) { this.Focus(); base.OnMouseDown(e); } protected override bool IsInputKey(Keys keyData) { if (keyData == Keys.Up || keyData == Keys.Down) return true; if (keyData == Keys.Left || keyData == Keys.Right) return true; return base.IsInputKey(keyData); } protected override void OnEnter(EventArgs e) { this.Invalidate(); base.OnEnter(e); } protected override void OnLeave(EventArgs e) { this.Invalidate(); base.OnLeave(e); } protected override void OnPaint(PaintEventArgs pe) { base.OnPaint(pe); if (this.Focused) { var rc = this.ClientRectangle; rc.Inflate(-2, -2); ControlPaint.DrawFocusRectangle(pe.Graphics, rc); } } } 

VB.NET中的Hans Passant代码

 Imports System Imports System.Drawing Imports System.Windows.Forms Public Class SelectablePanel Inherits Panel Public Sub SelectablePanel() Me.SetStyle(ControlStyles.Selectable, True) Me.TabStop = True End Sub Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs) Me.Focus() MyBase.OnMouseDown(e) End Sub Protected Overrides Function IsInputKey(ByVal keydata As Keys) As Boolean If (keydata = Keys.Up OrElse keydata = Keys.Down) Then Return True If (keydata = Keys.Left OrElse keydata = Keys.Right) Then Return True Return MyBase.IsInputKey(keydata) End Function Protected Overrides Sub OnEnter(ByVal e As EventArgs) Me.Invalidate() MyBase.OnEnter(e) End Sub Protected Overrides Sub OnLeave(ByVal e As EventArgs) Me.Invalidate() MyBase.OnLeave(e) End Sub Protected Overrides Sub OnPaint(ByVal pe As PaintEventArgs) MyBase.OnPaint(pe) If (Me.Focused) Then Dim rc As Rectangle = Me.ClientRectangle rc.Inflate(-2, -2) ControlPaint.DrawFocusRectangle(pe.Graphics, rc) End If End Sub End Class 

在点击事件中调用焦点

 private void Panel_Click(object sender, EventArgs e) { Panel.Focus(); } 

要获得焦点,请在“属性”窗口中检查MouseEnter事件。

写下面的代码:

 private void mainPanel_MouseEnter(object sender, EventArgs e) { mainPanel.Focus(); } 

我使用最简单的技巧,因为任何原因,我不能使用父窗体KeyPreview属性,使窗体句柄的关键事件,是把一个文本框

小组:

 Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0}); 

并用它来捕获KeyDown事件:

 _focusTextBox.KeyDown += panel_KeyDown; 

最后一步是在点击面板上的其他控件时将焦点设置到该文本框中:

 _focusTextBox.Focus(); 

面板没有得到重点,如果你想跟踪离开并input事件,你必须select面板

panel1.Select()事件中调用panel1.Select()