9
votes

Dois-je vraiment appeler Focus dans Onmousedown de mon contrôle personnalisé?

Je suis en train de mettre en œuvre un contrôle personnalisé qui hérite de Control code>. Je veux que cela soit concenable (c'est une sorte de boîte de liste).

dans le constructeur, je fais p> xxx pré>

i peut maintenant utiliser l'onglet pour naviguer vers le contrôle. P>

Toutefois, lorsque la commande reçoit un clic de souris, il ne réclamera pas automatiquement la mise au point. Bien sûr, je peux travailler autour de cela: P>

protected override void OnMouseDown(MouseEventArgs e)
{
    Focus();
    base.OnMouseDown(e);
}


3 commentaires

@THOMAS: Vous mentionnez "J'ai déjà eu le rectangle de focus en place": faites-vous cela par sur-chevalisation ongotfocus et surlostfocus et appelant ControlPaint.DrawfocusRectangle? Apprécier toute réponse.


@BILLW: Oui, c'est ce que je fais. Ongotfocus et OnlostFocus Invalidate Le rectangle contenant le rectangle de mise au point; Onpaint Vérifie la propriété de la propriété et des appels ControlPaint.DrawfocusRectangle au besoin.


Votre patient réponses à mes questions très appréciées! Je pose une autre réponse qui est la seule façon dont je puisse obtenir cela pour travailler dans Visual Studio RC1 compilé contre le cadre 3.5 (complet). Par "travail": je veux dire que lorsque la commande est "ongled-to:", il reçoit un rectangle de sélection affiché et lorsque "Tabous-abscente-de" le rectangle de sélection disparaît: et lorsque vous avez cliqué sur la commande, le rectangle de sélection est affiché.


3 Réponses :


4
votes

Démontage à la rescousse! Il s'avère que

SetStyle(ControlStyles.UserMouse, true);


3 commentaires

Ce n'est pas correct. Désactiver le style Uermouse ne doit être effectué que pour les emballages de classe de contrôle autour des contrôles natifs qui implémentent leur propre traitement de message de souris. Vous permettez à un contrôle de prendre la mise au point car vous êtes intéressé par les événements de saisie. Tourner intentionnellement le traitement des événements d'intrants n'a pas de sens.


La phrase "Le contrôle fait son propre traitement de la souris" est une confusion supplémentaire à la lumière de votre clarification: le contrôle Winforms fait son propre traitement de la souris (remplacement onmousedown etc.) Ou le contrôle natif fait-il son propre traitement de la souris (ce qui signifie que le contrôle WinForms devrait rester à l'abri)? Quoi qu'il en soit, apparemment usermouse était faux par défaut. Et puisque je n'envoie pas de contrôle natif, il devrait être vrai , non?


Oui, il appelle la méthode onmousedown. Que vous remplaceriez pour donner votre propre comportement de la souris. Comme lui donner le focus. Votre contrôle hérite d'un contrôle, il n'y a pas de contrôle de Windows natif étant enveloppé (comme ListBox ou TreeView). C'est juste une fenêtre simple.



2
votes

Oui, ce que vous devriez faire. Il existe de nombreux contrôles qui n'ont pas de moyen significatif de prendre la mise au point. Picturebox, panneau sont de bons exemples. Tout ce qui dérive de ContainControl. Control.onMoussedown () n'appelle donc pas automatiquement la mise au point () dans Onmousedown ().

Il suffit de remplacer la méthode Onmousedown ne suffit pas, vous devez également préciser l'utilisateur que votre contrôle a la mise au point. Alors elle aura une idée où vont les coups de clavier. Cela nécessite de déverrir sur l'onduleur () afin que vous puissiez dessiner un rectangle de mise au point. Controlpaint.DrawfocusRectangle () est une implémentation de la batterie pour cela.

Mais prendre la mise au point n'est vraiment utile que si vous faites quelque chose de significatif avec les messages du clavier. Donc, vous devrez remplacer également ONKEYDOODDOWDOWDOWDOWD. Et montrer des commentaires à l'utilisateur afin qu'elle puisse voir ce qu'elle a tapé. Si vous n'avez pas de mise en œuvre utile pour cela, vous ne devriez pas prendre la mise au point. Qui est pourquoi picturebox ne "


3 commentaires

Bons points, mais pourquoi avez-vous pensé que je voulais que le contrôle soit concentré au premier endroit? J'ai déjà eu le rectangle de mise au point en place et je travaille maintenant sur les gestionnaires de clavier.


Toujours bon de mentionner ce genre de détails dans la question.


J'ai mentionné entre parenthèses que c'est une sorte de liste de liste, ce qui implique de supporter de gérer des touches; Je ne voulais pas distraire de la question en mentionnant tous ces détails. Mais vous avez raison: il est bon de donner des informations sur la partie "Pourquoi voudriez-vous que cette" partie, car parfois il s'avère que vous voulez réellement résoudre ou contourner le problème sous-jacent de manière totalement différente!



0
votes
  1. compile dans un projet WinForms pour le cadre 3.5 P> LI>

  2. Faites glisser une instance de contrôle1 de la boîte à outils sur une surface de formulaire ... Assurez-vous que sa propriété TabStop est définie sur 'TRUE P> LI>

  3. mettre d'autres contrôles sur la forme. p> li>

  4. Vérifiez que lorsque l'instance de Control1 est tabulée à: il affiche un rectangle de sélection qui disparaît comme vous "TAB TAB". p> li>

  5. Vérifiez si vous cliquez sur l'instance de Control1 indiquant le rectangle de sélection et si vous cliquez sur un autre contrôle, il disparaît. P>

    namespace testFocusableControl
    {
        //  VS Studio 2010 RC1 : Tested against FrameWork 3.5 Full (not 'Client)
    
        public class Control1 : Control
        {
            public Control1()
            {
                SetStyle(ControlStyles.UserMouse, true);
            }
    
            protected override void OnLostFocus(EventArgs e)
            {
                this.Invalidate();
                base.OnLostFocus(e);
            }
    
            protected override void OnGotFocus(EventArgs e)
            {
                this.Invalidate();
                base.OnGotFocus(e);
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                if (this.Focused)
                {
                    ControlPaint.DrawFocusRectangle(e.Graphics, this.ClientRectangle, Color.Red, Color.Blue);
                }
                base.OnPaint(e);
            }
        }
    }
    

2 commentaires

Les méthodes que vous avez marquées comme // aucun effet ne fonctionnent pas car vous les avez déclarés virtuel , pas remplacer . Apparemment userpaint et sélectionnable par défaut sur true . Quant à # 6: Ne pas comprendre votre code est toujours mauvais, que cela fonctionne. Mais je pense que nous comprenons maintenant ce que fait et ne fonctionne pas et pourquoi, non? :)


+1 Merci beaucoup, Thomas pour vos idées. J'ai révisé le code pour incorporer votre informatin. !