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.
ps: I am programming in C# .NET v3.5, using VS2008. It's a Windows.Forms application, not WPF .
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);
}
}
}
The code from Hans Passant translated to VB.NET
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class SelectablePanel
Inherits Panel
Public Sub New()
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
call focus in click event
private void Panel_Click(object sender, EventArgs e)
{
Panel.Focus();
}
To get the focus,check for MouseEnter event in Properties window.
Write below code:
private void mainPanel_MouseEnter(object sender, EventArgs e)
{
mainPanel.Focus();
}
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();
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.