Définir le focus sur un .NET UserControl…?

Je crée un contrôle personnalisé dérivé de UserControl sur lequel j’aimerais définir le focus.

Le contrôle personnalisé contient un contrôle ComboBox et je dessine des chaînes à côté de celui-ci.

La ComboBox peut recevoir le focus, mais j’aimerais pouvoir définir le focus sur le contrôle UserControl lui-même. Mon gestionnaire OnPaint est configuré pour dessiner le contrôle légèrement différemment s’il a le focus, mais j’appelle CanFocus () à partir du formulaire parent lorsque je crée mon contrôle personnalisé et qu’il renvoie false.

Y a-t-il une propriété ou quelque chose à définir?

UserControl vous combattra bec et ongles pour ne pas avoir le focus. Il a un code qui passe automatiquement le focus à un contrôle enfant (le cas échéant) s’il obtient le focus. Vous devez au minimum remplacer WndProc () et intercepter le message WM_SETFOCUS. Il se peut que d’autres opérations soient nécessaires, comme ControlStyles.Selectable et les propriétés TabStop et TabIndex.

Votre prochain problème est que UserControl ne répondra pas de manière significative, par exemple, aux messages du clavier lorsqu’il aura le focus. Vous devez détecter les clics sur l’arrière-plan de l’UC pour gérer les messages de la souris, ainsi que remplacer le dessin afin qu’il soit évident pour l’utilisateur que l’UC a le focus (utilisez ControlPaint.DrawFocusRectangle). Si cela commence à sembler peu attrayant, c’est parce que l’UC était vraiment destiné à être un contrôle de conteneur.

De http://msdn.microsoft.com/en-us/library/system.windows.forms.control.canfocus.aspx

Remarques

Pour qu’un contrôle reçoive le focus d’entrée, un contrôle doit lui être atsortingbué, et les propriétés Visible et Enabled doivent être définies sur true pour le contrôle et tous ses contrôles parents. Le contrôle doit être un formulaire ou une commande. le parent le plus externe du contrôle doit être une forme.

Assurez-vous de respecter ces conditions préalables.

trop long pour un commentaire, inclut le lien et le code … mais ceci est un commentaire …

Beaucoup de gens se sont plaints du fait qu’un UserControl ne déclenche pas l’événement ‘GotFocus (). Par exemple: UserControl et GotFocus () fyi: LostFocus () se déclenchera comme prévu, selon mon expérience. Dans le passé, dans un projet à plusieurs formulaires, j’avais déjà implémenté les gestionnaires d’événements ‘Enter et’ Leave sur un UserControl sur chaque formulaire et constaté que ‘Entrée n’était appelé qu’une fois lors du chargement du formulaire.

Évidemment, les contrôles sur le contrôle UserControl “prennent le focus” (d’une manière que je ne peux pas expliquer, mais peut-être que l’un des gourous WinForms de SO le fera). Peut-être est-ce lié au fait que UserControl descend de ContainerControl?

J’ai expérimenté l’écriture d’un gestionnaire ‘GotFocus ():

private void Control_GotFocus(object sender, EventArgs e) { Console.WriteLine("Control GotFocus : " + ((sender as Control).Name)); } 

Ensuite, dans l’événement UserControl ‘Load, tous les contrôles du contrôle UserControl ont été connectés à ce gestionnaire d’événements. lors de la commutation entre les formulaires.

La seule autre chose mentionnée dans cette situation est de vérifier que la propriété IsTabStop de UserControl est définie sur True pourrait s’appliquer dans votre cas.

Une autre suggestion, qui consistait à écrire un gestionnaire d’événements MouseDown ou MouseClick pour UserControl, et dans cet appel: this.SetFocus(); m’a conduit nulle part.

J’espère que vous obtenez une réponse!

Dans certains cas, il est également souhaitable de ne pas laisser le focus se déplacer sur les éléments enfants d’un UserControl.
Dans ce cas, vous devez également définir ControlStyles.ContainerControl sur false.

 Public Sub New() InitializeComponent() Me.SetStyle(ControlStyles.ContainerControl, False) Me.SetStyle(ControlStyles.Selectable, True) End Sub 

Disons que vous avez une image sur votre contrôle utilisateur et que vous souhaitez la mettre en surbrillance en imitant l’événement “GetFocus” (par exemple, le focus sur votre contrôle utilisateur prend cette image). L’accent mis sur votre contrôle utilisateur sera traité en traçant une ligne de contour pointillée dans le PictureBox. Cela se fait via les événements de contrôle utilisateur OnEnter et OnLeave. Voici la procédure en surbrillance …

 Public Sub highlightImage() Dim l As Single() = {2, 2, 2, 2} Dim p As New Pen(Color.Gray, 1) p.DashPattern = l Dim g As Graphics = picColor.CreateGraphics() g.DrawRectangle(p, 0, 0, picColor.Width - 1, picColor.Height - 1) End Sub 

Ces deux dérogations feront le travail.

 Protected Overrides Sub OnEnter(e As EventArgs) MyBase.OnEnter(e) Me.highlightImage() End Sub Protected Overrides Sub OnLeave(e As EventArgs) MyBase.OnLeave(e) MyBase.Refresh() End Sub 

Si UserControl obtient le focus, il le transmet en interne à son contrôle enfant.

Vous devrez donc ignorer l’exécution du code qui définit le contrôle sur le contrôle des enfants. Pour cela, vous devez remplacer WndProc () et ignorer l’exécution de tout message WM_SETFOCUS.

  public class FocusableUserControl : UserControl { protected override void WndProc(ref Message m) { switch (m.Msg) { case (int)Win32Constants.WM_SETFOCUS: //Returning from here will skip setting focus to child controls. //It will not skip setting focus to this control. Console.WriteLine("FocusableUserControl is focused: " + Focused); return; } base.WndProc(ref m); } } 

Où WM_SETFOCUS est “0x0007”.