IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Différences de réactions entre new et override en mode design


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut Différences de réactions entre new et override en mode design
    Bonjour,

    Je comprends mal un phénomène qui se passe lorsque je dérive un contrôle à partir du TextBox.

    Pour faire simple, j'ai surchargé ma propriété "BackColor", ce qui me permet, outre les nouvelles possibilités de mon contrôle, de disposer de 2 couleurs distinctes, une lorsque le controle est en mode lecture/écriture, et l'autre lorsque le contrôle est en ReadOnly (j'ai donc une seconde propriété BackReadOnlyColor).

    Tout fonctionne en fait parfaitement si j'opère comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
            [Browsable(true)]
            [Description("Obtient ou définit la couleur de fond en mode lecture/écriture")]
            [DefaultValue(typeof(SystemColors),"Window")]
            [Category("BgProp")]
            public new Color BackColor
            {
                get { return backColor; }
                set
                {
                    backColor = value;
                    if (!base.ReadOnly)
                        base.BackColor = value;
                }
            }
    En effet, comme ceci, lorsque je me place en mode design, j'ajoute mon contrôle sur la form, pas de problème. Je change la couleur de fond, toujours pas de problème, ça fonctionne comme un TextBox ordinaire.

    Par contre, si je remplace le mot clé "new" par "override", ça ne fonctionne plus du tout de la même façon. En effet :

    - Je place mon contrôle sur la form : aucun problème, il apparaît avec sa couleur de fond par défaut.

    - Je change la couleur de fond : rien ne se passe, le contrôle ne subit pas la modification de BackColor

    - Je clique sur un autre contrôle de la form (perte du focus en mode design) : la partie contenant du texte de mon contrôle se colorie avec la couleur de fond (coloriage partiel ???), comme ceci :



    - Je recompile avec F6, la couleur de fond est alors correcte :



    J'avoue ne pas comprendre du tout comment j'arrive de la sorte à remplir partiellement la couleur de fond d'un contrôle (fonction non prévue), et pourquoi le remplissage correct ne s'effectue qu'en recompilant avec F6.

    Avec new, ça fonctionne parfaitement, et donc je ne suis pas bloqué, mais j'ai quand même besoin de savoir le mécanisme qui amène à ce fonctionnement.

    Notez qu'en mode exécution, le fonctionnement est identique et le contrôle utilisé avec override fonctionne comme celui avec new, l'anomalie n'apparaît qu'en mode design.

    J'ajoute que "override" me semblait plus approprié que "new", parce que si j'accède à la propriété BackColor dans un programme en faisant un cast (TextBox) de mon contrôle, ça me permettait, contrairement à new, d'accéder à la propriété dérivée. Avec "new", j'accéderais à la propriété de TextBox, et donc fonctionnement incorrect éventuel.

    Merci d'avance

    Claude

  2. #2
    Membre Expert
    Avatar de laedit
    Homme Profil pro
    Consultant études et développement
    Inscrit en
    Décembre 2006
    Messages
    1 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant études et développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 344
    Par défaut
    Si cela marche lors de l'exécution c'est l'essentiel. Mais il est toujours préférable d'utiliser override si tu le peux plutôt qu'un new.

    Pour le cast, plutôt que de le faire en TextBox, pourquoi ne le fais-tu pas directement dans le type de ton contrôle ?
    Blog - Articles - Framework

    MSDN vous aide, si si, alors n'hésitez pas à y faire un tour avant de poser une question.
    Ah, et n'oubliez pas, Google peut répondre à la majorité de vos questions.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Les modifications que tu apportes aux contrôles personnalisés ne sont pas prises en compte jusqu'à ce que tu recompiles.

    Quand tu utilises new, tu "masques" la propriété BackColor de la classe de base. Cela signifie qu'elle ne sera considérée que si tu manipules le contrôle via une variable de type MyTextBox (en supposant que tu l'aies appelé comme ça). Si tu le manipules via une variable de type TextBox, le polymorphisme ne joue pas car tu n'as pas redéfini la même propriété, tu en as créé une nouvelle : c'est donc la propriété BackColor de la classe de base qui est utilisée. Pour que ta propriété soit prise en compte dans le polymorphisme, il faut faire un override.

    En gros, voilà ce qui se passe :
    Le dessin du contrôle est géré par une classe parente de ton contrôle, en faisant appel à la propriété BackColor. Si tu utilises new, ce n'est pas ta propriété BackColor qui est utilisée, mais celle de la classe de base. D'ailleurs tu vois que le contrôle s'affiche bien en blanc, même si ta propriété backColor n'est pas initialisée à White, car base.BackColor vaut White. Par contre, quand tu affectes une valeur à BackColor, puisque tu l'affectes aussi à base.BackColor ça marche bien.
    Si tu utilises override, grâce au polymorphisme c'est bien ta propriété BackColor qui est utilisée. Le contrôle apparait donc avec la couleur initiale que tu as définie.

    Par contre je ne comprends pas trop pourquoi il faut recompiler quand tu changes de couleur...

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Salut
    -----

    Merci pour les réponses. Je vais tâcher de préciser.

    Dans l'ordre :

    Si cela marche lors de l'exécution c'est l'essentiel. Mais il est toujours préférable d'utiliser override si tu le peux plutôt qu'un new.
    Ben justement, c'est avec le override que j'ai un soucis. Je sais bien que l'important c'est l'exécution, mais si j'ai un comportement anormal c'est qu'il se passe quelque chose que je n'ai probablement pas bien compris, et je n'ai pas envie de me faire piéger sur quelque chose de plus complexe mettant en oeuvre le même mécanisme.

    Pour le cast, plutôt que de le faire en TextBox, pourquoi ne le fais-tu pas directement dans le type de ton contrôle ?
    Je n'ai pas de cast à faire, c'était juste pour souligner la différence entre override et new.

    Les modifications que tu apportes aux contrôles personnalisés ne sont pas prises en compte jusqu'à ce que tu recompiles.
    Oui, ça je sais.
    quand je place mon contrôle dans ma fenêtre, j'ai bien sûr tapé F6 avant pour recompiler.

    Pour que ta propriété soit prise en compte dans le polymorphisme, il faut faire un override.
    D'accord, c'est bien comme ça que je l'avais compris, et c'est pourquoi je voulais faire un override.

    Si tu utilises override, grâce au polymorphisme c'est bien ta propriété BackColor qui est utilisée. Le contrôle apparait donc avec la couleur initiale que tu as définie.
    Ben justement. Avec new ça fonctionne parfaitement, mais pas avec override.

    Je viens de faire plusieurs essais. J'ai créé un contrôle dérivé de TextBox qui ne contient rien du tout, juste la propriété BackColor. Voici la classe complète, ultrasimple puisqu'elle ne fait rien : une propriété et un attribut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    namespace test
    {
        public partial class ControlTest : TextBox
        {
            private Color backColor = Color.White;
     
            public new Color BackColor 
            {
                get
                {
                    return backColor;
                }
     
                set
                {
                    backColor = value;
                    base.BackColor = value;
                }
            }
        }
    }
    Ecrit comme ça, le contrôle fonctionne strictement comme le TextBox original, ce qui me semble logique.

    Maintenant, je remplace simplement dans ce qui précède le mot "new" par le mot "override".
    Et bien, ça ne fonctionne plus :

    - Je recompile avec F6
    - Je place mon contrôle sur la fenêtre : OK
    - J'y écrit un texte : OK
    - Je change la propriété BackColor : rien ne se passe, le contrôle reste blanc
    - Je clique ailleurs dans ma fenêtre : le texte s'écrit sur fond de ma BackColor et le reste du contrôle (là où il n'y a pas de texte) reste blanc (voir capture sur mon premier post)
    - Je retape <F6>, le contrôle se colorie correctement dans la couleur de fond.
    A chaque changement de couleur, je dois taper <F6>.
    Si je ne tape pas F6 et que je clique ailleurs que dans mon contrôle, j'obtiens un contrôle bicolore : sous le texte la nouvelle couleur, et ailleurs l'ancienne.

    Par contre, si j'écris ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
            public override Color BackColor 
            {
                get
                {
                    return base.BackColor;
                }
     
                set
                {
                    backColor = value;
                    base.BackColor = value;
     
                }
    Ca refonctionne de nouveau.
    La seule différence, c'est que je renvoie base.BackColor au lieu de l'attribut privé backColor, qui, pourtant, vaut d'office base.BackColor, puisque dans le set elles sont mises à la même valeur.

    Autrement dit :

    Avec new + renvoi de l'attribut privé backColor : ça fonctionne
    Avec new + renvoi de la propriété de la base : ça fonctionne
    Avec override + renvoi de la propriété de la base : ça fonctionne
    Avec override + renvoi de l'attribut privé backColor : ça ne fonctionne plus.

    Et non seulement dans le dernier cas ça ne fonctionne plus, mais en plus ce que j'obtiens est incompréhensible (zone sous le texte d'une couleur et le reste du contrôle d'une autre). Je ne peux m'imaginer l'explication que si le redessin du text dans le contrôle de base plaçait la bonne couleur de fond, mais sans s'occuper du reste de la zone. Et pour ça, je ne comprends pas quel mécanisme opère.

    Or, je ne peux pas renvoyer base.BackColor dans mon vrai contrôle, parce que base.Backcolor peut être soit "backColor", soit "backReadOnlyColor" selon que mon contrôle soit ou non en mode ReadOnly. C'est pourquoi j'ai besoin d'une copie de la propriété sous forme d'attribut pour renvoyer toujours la couleur BackColor correspondant au mode non ReadOnly.

    Si vous avez une idée ?
    Merci

    Claude

  5. #5
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par ClaudeBg Voir le message
    Si vous avez une idée ?
    Oui Si tu évitais de surcharger BackColor, et avais à la place un NonReadOnlyBackColor ?

    Tu peux après surcharger le get et le set de BackColor (en override) pour qu'il renvoie ou affecte NonReadOnlyBackColor ou ReadOnlyBackColor selon que ton objet est ReadOnly ou pas.

    Voire même, le mieux est peut être de surcharger le paint, pour qu'il prenne l'une ou l'autre couleur en fonction de readonly. Ca t'éviterait de surcharger BackColor.

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Salut
    ------

    Si tu évitais de surcharger BackColor, et avais à la place un NonReadOnlyBackColor ?
    Oui, ça j'y ai pensé.
    Ce n'est pas trouver une solution qui m'interpelle, il me suffit d'utiliser une de tes méthodes, que j'ai déjà utilisées dans d'autres contrôles plus complexes.

    Ce que je cherche, c'est à comprendre la raison du fonctionnement curieux de l'override avec l'attribut, parce que je crains que ce problème ne survienne dans d'autres circonstances beaucoup plus difficiles à identifier.
    Je me dis que si je ne comprends pas ce qui se passe, c'est que j'ai du louper quelque chose, je cherche à savoir quoi

    Bref, je cherche plus une explication qu'une solution

    Claude

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Difference entre New et (virtual / override)
    Par shimomura22 dans le forum C#
    Réponses: 2
    Dernier message: 16/04/2015, 21h08
  2. Benchmark : différence de rapidité entre new Array() et []
    Par Boa67 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 14/06/2009, 17h31
  3. Réponses: 6
    Dernier message: 06/12/2005, 16h51
  4. Différences d'affichage entre IE et FF
    Par Tot-O dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 22/09/2005, 18h47
  5. [C#] new et override
    Par jab dans le forum Windows Forms
    Réponses: 4
    Dernier message: 23/10/2004, 23h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo