小组没有得到重点
我正在继续在我简单的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()