c# - propiedad - El panel no se enfoca
propiedad tag c# (6)
Continúo programando algún tipo de navegación con el teclado en mi sencillo programa gráfico (usando C #). Y me encontré con problemas una vez más.
Mi problema es que quiero procesar la entrada del teclado para mover una capa. Mover la capa con el mouse ya funciona bastante bien, pero el control no obtiene el foco ( ni KeyUp / KeyDown / KeyPress ni GotFocus / LostFocus se activan para este control ). Como mi clase proviene del Panel (y sobrescribe un par de eventos), también he sobrescrito los eventos mencionados anteriormente, pero no puedo lograr que se desencadenen esos eventos.
Creo que podría implementar la respuesta del teclado utilizando algo como Keyboard.GetState () o ProcessCmdWnd o algo así. Sin embargo: todavía tengo que ser capaz de decir cuándo el control obtuvo el foco.
¿Hay alguna forma más o menos elegante de agregar esta capacidad a un control de usuario (que se basa en el Panel)?
He revisado muchos hilos aquí y podría usar este enfoque para ingresar el teclado. Sin embargo, el problema de enfoque aún permanece.
¡Muchas gracias por la información con anticipación!
Igor.
ps: estoy programando en C # .NET v3.5, usando VS2008. Es una aplicación Windows.Forms, no WPF .
El mismo código de Hans Passant en 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
El truco más simple que uso cuando por alguna razón no puedo usar la propiedad principal Form KeyPreview para hacer que el Formulario maneje eventos clave, es poner un Textbox en
El panel:
Panel.Controls.Add(_focusTextBox = new TextBox() { Visible = true , Left = -300, TabIndex = 0});
Y úsala para capturar el evento KeyDown:
_focusTextBox.KeyDown += panel_KeyDown;
El último paso es establecer el foco en este cuadro de texto cuando los otros controles en el panel hicieron clic:
_focusTextBox.Focus();
La clase Panel fue diseñada como contenedor, evita tomar el foco para que el control infantil siempre lo obtenga. Necesitará una cirugía para arreglar eso. Introduje el código para obtener las pulsaciones de tecla del cursor en el evento KeyDown también:
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);
}
}
}
Los paneles no se enfocan, debe seleccionar el panel si desea rastrear el permiso e ingresar eventos
llame al panel1.Select()
en el evento MouseClick
Para obtener el foco, verifique el evento MouseEnter en la ventana de Propiedades.
Escriba el código siguiente:
private void mainPanel_MouseEnter(object sender, EventArgs e)
{
mainPanel.Focus();
}
llame al foco en el evento click
private void Panel_Click(object sender, EventArgs e)
{
Panel.Focus();
}