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

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    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 émérite
    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 : 36
    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
    Points : 2 265
    Points
    2 265
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    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 éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    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 émérite Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    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 éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    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

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    ok ok Jouons à Sherlock !

    hum...

    Tu dis donc que dans ton dernier petit exemple qui résume le problème, tu as un comportement différent selon que tu renvoies this.backColor ou base.BackColor quand tu overrides.
    Or ton set assure que ces deux variables ont la même valeur.
    Y'a donc un truc qui nous échappe.
    Si tu rajoutes un if(this.backColor != base.BackColor) throw new Exception(); dans ton get, est-ce que l'exception est déclenchée ? (le pétage d'exception est la meilleure façon, il me semble, de débuguer du code exécuté par le designer )
    ಠ_ಠ

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Si tu rajoutes un if(this.backColor != base.BackColor) throw new Exception(); dans ton get, est-ce que l'exception est déclenchée ?
    Excellente idée .
    J'ai fait l'essai.

    J'ai d'abord eu immédiatement une exception, mais c'est parce qu'à la création, backColor n'avait pas la même valeur que base.BackColor, c'était logique.

    J'ai donc ajouté un constructeur de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            public ControlTest() : base()
            {
                this.backColor = base.BackColor;
            }
    Ensuite, j'ai refait la manipulation à partir du début.

    - Placement du contrôle -> OK
    - Ajout d'un texte -> OK
    - Changement de couleur -> Exception générée.

    J'ai alors ajouté un texte dans l'exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    throw new Exception(backColor.ToString() + " / " + base.BackColor.ToString());
    Et en récupérant l'exception, je m'aperçois que dès que je tente de changer la couleur :

    - backColor prend la nouvelle valeur choisie dans les propriétés du designer
    - base.BackColor ne change pas de valeur et conserve sa valeur originale.

    Donc, dans le set, la valeur ne semble pas se répercuter sur base.BackColor, seul l'attribut local est modifié.

    Ca explique parfaitement pourquoi le contrôle ne change pas de couleur à ce moment. Evidemment, ça n'explique pas pourquoi la valeur n'est pas répercutée.

    Par contre, dès qu'on tape <F6> pour recompiler, le contrôle de base se trouve affecté de la nouvelle valeur.

    La question initiale devient donc : pourquoi le set modifie-t-il la valeur de l'attribut local mais pas la valeur de la propriété de base?

    Et, plus curieux, pourquoi si le get renvoie la valeur de la propriété de base, celle-ci est-elle bien modifiée, alors que si on renvoie l'attribut elle ne l'est pas?

    Le fonctionnement semble correspondre à un truc du genre :
    - Si la valeur lue par get = la valeur de la propriété de base, celle-ci n'est pas modifiée
    - Si la valeur lue par get != la valeur de la propriété de base, celle-ci est modifiée.

    Je me suis dit que le premier appel de set semblait ne pas modifier base.BackColor mais bien backColor, ce qui expliquerait qu'un second appel remettre les choses en ordre.

    Peut-être le set s'interromprait-il en cours d'exécution?
    J'ai alors essayé d'inverser l'ordre d'initialisation dans le set, aucun changement.

    J'ai alors tenté de modifier le set de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                set
                {
                    base.BackColor = value;
                    backColor = base.BackColor;
                }
    Dans ce cas, clairement, backColor ne peut pas valoir autre chose que base.BackColor, même si un premier passage n'initialiserait pas correctement la propriété de base. Au pire, si l'initalisation de base.BackColor était "défectueuse", l'attribut aurait la même fausse valeur non modifiée.

    Impossible qu'il en soit autrement, pas vrai?

    Essais tenté, le contrôle continue de fonctionner de façon incorrecte, et si je remets la ligne d'exception, j'ai de nouveau une exception avec strictement le même résultat : backColor = bonne couleur, base.BackColor = ancienne couleur.

    mon backColor se retrouve bien avec la couleur que je viens de choisir. Vu qu'il l'a lu dans la propriété de base, il ne fait aucun doute que le set a bien modifié base.BackColor avec la bonne valeur.

    Moralité, mon "set" modifie bel et bien la propriété de base, mais celle-ci est remodifiée immédiatement après par un mécanisme que je ne comprends pas.

    Ce mécanisme n'agit de plus que si on travaille en mode override et que si on renvoie la valeur de l'attribut au lieu de renvoyer la valeur de la propriété.

    Ca commence à ressembler plus à de l'alchimie qu'à de l'informatique.

    Vous avez d'autres pistes pour continuer l'enquête?

    Claude

  9. #9
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    La première piste que je vois pour comprendre ce qui se passe dans le designer, c'est de debugger Visual Studio (si si, c'est possible )

    Ouvre une 2e instance de VS
    Ouvre le fichier source de ton contrôle
    Vas dans Debug -> Attach to process, et sélectionne le process devenv.exe où ton projet est ouvert
    Mets un breakpoint où tu veux dans ton code, quand le designer appelera ce code, le process sera suspendu et tu pourras voir ce qui se passe

    Plus d'infos sur sur MSDN

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut

    Ouvre une 2e instance de VS...
    Ah, super la méthode.
    J'ai déjà debuggé en mode design, mais en modifiant la propriété de debuggage pour lancer une nouvelle instance de VS.
    Ta méthode me semble plus simple, je l'adopte

    Bon, donc, debuggage sur le set :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                set
                {
                    base.BackColor = value;
                    backColor = base.BackColor;
                }
    Sur le get, il est appelé chaque fois qu'on tente de changer de fenêtre (rafraîchissement) et donc si j'y place un point d'arrêt je ne sais plus revenir à mon VS principal.

    Je place un point d'arrêt sur chaque ligne.
    Je pars d'un contrôle déjà configuré en couleur bleue (pour voir d'éventuelles différences entre valeur actuelle et valeur par défaut : la suite montre que j'ai eu raison).

    Je vais dans les propriétés du contrôle, et je change la propriété BackColor en noir.

    - Le debuggage s'arrête sur "base.BackColor = value;". value vaut bien "noir", et base.BackColor est bien en bleu.

    - Je tape <F11> (pas détaillé). La routine set s'interrompt et le programme saute directement dans le get. Le get renvoie backColor, qui vaut donc "bleu".

    - Je tape <F11>. Seconde exécution de la ligne return backColor

    - <F11>. Le programme revient sur la seconde ligne du set. base.BackColor et value sont tous les deux en bleu

    - <F11>. Exécution de la seconde ligne du set. backColor et base.BackColor valent maintenant tous les deux "noir". ????

    Dit autrement : avant exécution de la ligne "backColor = base.BackColor"

    Les deux valaient "bleu".

    J'avais donc :
    backColor = bleu.

    J'exécute la ligne, et je me retrouve avec :

    backColor = base.BackColor = noir.

    L'affectation de base.BackColor vers backColor a modifié la valeur de base.BackColor vue par VS. ??

    en écrivant : a = b j'ai modifié b ???

    Je retape <F11>. Retour à l'instruction du get, qui renvoie backColor = noir.
    Tout est maintenant en noir.

    Je reviens à ma fenêtre en mode design, et le contrôle .... est resté bleu, bien que la fenêtre de propriété m'indique bien "noir".

    Je tape <F6> dans le VS initial en mode design.

    Arrêt sur l'instruction du constructeur :"this.backColor = base.BackColor;". Or, maintenant base.BackColor = blanc, ce n'est plus la même instance du contrôle que celui en mode design, puisque ces valeurs étaient sur noir.

    <F11>. Arrêt sur la première ligne du set, j'ai maintenant : base.BackColor = blanc, et value = noir.

    <F11> : saut à la ligne du get. Donc le get retourne "blanc".

    <F11> : Seconde exécution de get : aucun changement

    <F11> : Retour sur la seconde ligne du set. A cet instant : backColor = base.BackColor = blanc, et value = noir.

    <F11> : exécution de la seconde ligne. De nouveau, le "miracle" opère : backColor = base.BackColor = value = noir.

    Retour dans le premier VS en mode design, le contrôle est maintenant noir.

    J'avoue que ça me dépasse un peu. Tout ceci ne correspond pas à ce que je connais du C#. Et même en cas de bug dans VS lui-même, je comprends mal que passer de new à override modifie son comportement.

    Claude

  11. #11
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    J'ai pas eu le temps de chercher en détails, mais en regardant avec reflector la propriété Control.Color, on voit que dans le set, il lit la valeur courante avant de la changer, et à nouveau après.

    C'est peut-être là qu'est le problème... tant que tu n'as pas modifié ton champ backColor, la propriété BackColor renvoie toujours l'ancienne valeur, et comme tu n'affectes ce champ qu'après base.BackColor, ça continue de renvoyer l'ancienne valeur

    Pour y voir plus clair tu peux essayer de debugger dans les sources du framework (Options -> Debug -> Enable .NET framework source stepping)

  12. #12
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    en fait, je viens de penser à une autre solution qui a l'air de marcher :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            public override Color BackColor
            {
                get { return backColor; }
                set
                {
                    backColor = value;
                    this.OnBackColorChanged(EventArgs.Empty);
                }
            }
    On ne touche plus du tout à base.BackColor, et on est plus emmerdé
    Il faut juste appeler OnBackColorChanged pour notifier le contrôle qu'il y a eu un changement et qu'il doit se redessiner

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Effectivement, c'est très subtil comme méthode et ça fonctionne parfaitement.


    De plus, ça démontre que ça fonctionne comme tu l'expliques, avec relecture et écriture de la valeur relue. Je trouve ça tordu d'avoir écrit le contrôle comme ça, mais bon il doit y avoir une raison.

    Si tu peux m'expliquer en 3 mots pourquoi ce phénomène ne se manifeste que si on met override et pas si on met new, j'aurais enfin tout compris
    Parce que c'est ce point particulier qui me pose le plus de problème de logique.

    Claude

  14. #14
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par ClaudeBg Voir le message
    Si tu peux m'expliquer en 3 mots pourquoi ce phénomène ne se manifeste que si on met override et pas si on met new, j'aurais enfin tout compris
    Parce que comme je l'ai dit plus haut, new crée une nouvelle méthode (ou propriété) sans rapport avec celle de la classe de base. La classe TextBox n'a aucune connaissance d'une propriété MaTextBox.BackColor déclarée avec new : du point de vue de TextBox, la propriété BackColor est celle définie dans TextBox (ou TextBoxBase, je sais plus).

    Par contre, si tu utilises override, tu redéfinis la méthode (ou propriété) de la classe de base. Par le mécanisme du polymorphisme, si le code de TextBox appelle this.BackColor, c'est ta propriété redéfinie qui sera appelée

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    si le code de TextBox appelle this.BackColor, c'est ta propriété redéfinie qui sera appelée
    Ah, ok, c'est ça que je n'avais pas saisi.

    Je pensais que si dans la classe de base on utilisait "this" pour lire la propriété, c'était la propriété de la classe de base qui était appelée et pas la propriété surchargée.

    J'avais bien saisi le polymorphisme pour le programme appelant, mais pas que l'override détournerait aussi les fonctions écrites dans la classe de base elle-même.

    Merci à vous pour les explications

    Claude

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Points : 2 925
    Points
    2 925
    Par défaut
    Pour compléter : quand une méthode est virtuelle, c'est la version la plus dérivée qui est appelée (que l'on soit à l'intérieur ou à l'extérieur de la classe).

    On peut juste appeler la version de la classe de base (enfin précisément de l'ancêter le plus proche ayant redéfini la méthode) en préfixant avec "base" (ce n'est donc possible qu'à l'intérieur de la classe, pas à l'extérieur).
    ಠ_ಠ

+ 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