web-dev-qa-db-fra.com

Le panneau ne se concentre pas

Je continue à programmer une sorte de navigation au clavier dans mon programme graphique simple (en C #). Et j'ai eu des ennuis encore une fois.

alt text

Mon problème est que je veux traiter l'entrée au clavier pour déplacer un calque. Déplacer le calque avec la souris fonctionne déjà assez bien, mais le contrôle n’a pas le focus ( ni KeyUp/KeyDown/KeyPress ni GotFocus/LostFocus n’est déclenché pour ce contrôle ). ma classe dérive de Panel (et écrase quelques événements), j'ai également écrasé les événements mentionnés ci-dessus, mais je ne peux pas réussir à les déclencher.

Je pense que je pourrais réussir à mettre en œuvre la réponse au clavier en utilisant quelque chose comme Keyboard.GetState () ou ProcessCmdWnd ou quelque chose. Cependant: je dois encore être capable de dire quand le contrôle a le focus.

Existe-t-il un moyen plus ou moins élégant d’ajouter cette possibilité à un contrôle utilisateur (basé sur Panel)?

J'ai vérifié beaucoup de discussions ici et je pourrais utiliser cette approche pour la saisie au clavier. Le problème de focalisation reste cependant toujours.

Merci beaucoup pour l'information à l'avance!

Igor.

p.s .: Je programme en C # .NET v3.5, avec VS2008. C'est une application Windows.Forms, pas WPF .

26
Igor

La classe Panel a été conçue en tant que conteneur, elle évite de prendre le focus de sorte qu'un contrôle enfant l'obtiendra toujours. Vous aurez besoin d'une intervention chirurgicale pour résoudre ce problème. J'ai ajouté le code pour obtenir des traits de touche de curseur dans l'événement KeyDown également:

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);
        }
    }
}
57
Hans Passant

Le même code Hans Passant dans 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
6
Oliver Miranda

L’astuce la plus simple que j’utilise lorsque, pour une raison quelconque, je ne peux pas utiliser la propriété parent KeyPreview de formulaire pour que le formulaire traite les événements de clé, consiste à placer une zone de texte sur 

Le panel:

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

Et utilisez-le pour capturer l'événement KeyDown:

_focusTextBox.KeyDown += panel_KeyDown;

La dernière étape consiste à définir le focus sur cette zone de texte lorsque d'autres contrôles du panneau ont cliqué:

_focusTextBox.Focus();
0
Eng. M.Hamdy

appelez le focus dans l'événement de clic

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

Pour obtenir le focus, recherchez l'événement MouseEnter dans la fenêtre Propriétés.

Écrivez ci-dessous le code:

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