问题
I am continuing to program some kind of keyboard navigation in my simple graphic program (using C#). And I ran into trouble once again.
My problem is that I want to process the keyboard input to move a layer around. Moving the layer with the mouse already works quite well, yet the control doesn't get the focus (neither KeyUp/KeyDown/KeyPress nor GotFocus/LostFocus is triggered for this control). Since my class derives from Panel (and overwrites a couple of events), I've also overwritten the events mentioned above, but I can't succeed in getting those events triggered.
I think I could manage to implement keyboard response either using something like Keyboard.GetState() or ProcessCmdWnd or something. However: I still have to be able to tell when the control got the focus.
Is there an more or less elegant way to add this ability to a user control (which is based on Panel)?
I've checked many threads in here and I might use this approach for keyboard input. The focus problem however still remains.
Thank you very much for information in advance!
Igor.
p.s.: I am programming in C# .NET v3.5, using VS2008. It's a Windows.Forms application, not WPF.
回答1:
The Panel class was designed as container, it avoids taking the focus so a child control will always get it. You'll need some surgery to fix that. I threw in the code to get cursor key strokes in the KeyDown event as well:
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);
}
}
}
回答2:
The same Hans Passant code in VB.NET
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
回答3:
call focus in click event
private void Panel_Click(object sender, EventArgs e)
{
Panel.Focus();
}
回答4:
To get the focus,check for MouseEnter event in Properties window.
Write below code:
private void mainPanel_MouseEnter(object sender, EventArgs e)
{
mainPanel.Focus();
}
回答5:
The simplest trick I use when for any reason I can’t use the parent Form KeyPreview property to make the Form handle key events, is to put a Textbox on
The panel:
Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0});
And use it to capture KeyDown event:
_focusTextBox.KeyDown += panel_KeyDown;
The last step is to set focus to this TextBox when other controls on the panel clicked:
_focusTextBox.Focus();
回答6:
Panels are not getting focus, you have to select the panel if you want to track leave and enter events
call panel1.Select()
in MouseClick
Event
来源:https://stackoverflow.com/questions/3562235/panel-not-getting-focus