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 :

Impossible de dessiner Image avec Graphics sur pictureBox


Sujet :

Windows Forms

  1. #1
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut Impossible de dessiner Image avec Graphics sur pictureBox
    Hello,

    je code un UserControl qui affiche une picturebox sensitive. Lors d'un clic je récupère la position du clic pour modifier l'image localement, en utilisant Graphics.

    mes fonctions sont correctement appelées, mais l'affichage ne change pas :/

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    private void InitializeComponent()
            {
                this.pictureBox1 = new System.Windows.Forms.PictureBox();
                ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
                this.SuspendLayout();
                // 
                // pictureBox1
                // 
                this.pictureBox1.Image = global::Projet1.Properties.Resources.image_defaut;
                this.pictureBox1.InitialImage = global::Projet1.Properties.Resources.imagedefaut;
                this.pictureBox1.Location = new System.Drawing.Point(0, 0);
                this.pictureBox1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
                this.pictureBox1.Name = "pictureBox1";
                this.pictureBox1.Size = new System.Drawing.Size(190, 190);
                this.pictureBox1.TabIndex = 0;
                this.pictureBox1.TabStop = false;
                this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
                this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
                // 
                // VueControlePTZ
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.Controls.Add(this.pictureBox1);
                this.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
                this.Name = "VueControlePTZ";
                this.Size = new System.Drawing.Size(190, 190);
                ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
                this.Paint += new System.Windows.Forms.PaintEventHandler(this.VueControlePTZ_Paint);
                this.ResumeLayout(false);
     
            }
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
            /// <summary>
            /// fonciton appelée lors du clic appuyé sur bouton de la souris
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void pictureBox1_MouseDown(object sender, MouseEventArgs e)
            {
                System.Console.WriteLine("pictureBox1_MouseDown() appelée");
     
                if (e.Button == MouseButtons.Left)
                {
                    PositionCliquable posCliquee = DefinirElementDePositionClique(e.X, e.Y);
     
                    //on vérifie que lon a bnien cliqué sur un élement sensitif
                    if (posCliquee != null)
                    {
                        //traitement d'affichage
                        posCourante = posCliquee;
                        UpdateVue();
                    }
                }
            }
     
            /// <summary>
            /// cette fonction permet de mettre à jour la vue
            /// </summary>
            private void UpdateVue()
            {
                pictureBox1.Image = pictureBox1.InitialImage;
                PositionCliquable posMarqueurCouleur = DefinirElementMarqueurCouleur();
     
                //A virer
                if (posMarqueurCouleur == null)
                    posMarqueurCouleur = this.positionBoutonEtatUtilise;
     
                using (Graphics g = CreateGraphics())
                {
                    try
                    {
                        //Si le marqueur couleur n'est aps null
                        //on est donc dans une logique d'utilisation
                        if (posMarqueurCouleur != null)
                        {
                            System.Console.WriteLine("dans UpdateVue()_1");
     
                            g.DrawImage(posMarqueurCouleur.Image, posMarqueurCouleur.CoordonneeHGImage);
     
                            System.Console.WriteLine("dans UpdateVue()_2");
                            //on regarde si le clic est actif => une posCourante existe
                            if (posCourante != null)
                            {
                                g.DrawImage(posCourante.Image, posCourante.CoordonneeHGImage);
                                System.Console.WriteLine("dans UpdateVue()_3 : on ecrit l'image supérieure");
                            }
                            System.Console.WriteLine("dans UpdateVue()_4");
                        }
                    }
                    catch(Exception e){ System.Console.WriteLine(e.Message);  System.Console.WriteLine(e.StackTrace); }
     
                    g.Dispose();
                }
            }
     
     
            /// <summary>
            /// Procédure de rappel sur evenement Paint
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void VueControlePTZ_Paint(object sender, PaintEventArgs e)
            {
                UpdateVue();
            }
    Sur evenement Paint j'appellle UpdateVue(), et lors d'une pression sur la souris, la même fonction est appelée au final.

    Quelqu'un peut m'expliquer ce qui cloche pour faire afficher cet élément ?

    Merci

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    salut

    déja dit ici et ailleurs

    C'est ton CreateGraphics qui te fout le bordel

    DAns le OnPaint() tu as un argument qui contient le contexte graphique

    Donc, il te faut le recuperer dans le OnPaint();

    D'ailleurs, tout les draw doivent y etre fait...

    En théorie, sur le mouseMove, tu dois changer les infos necessaires au Paint et faire un Invalidate() qui va appeler le OnPaint()

    Et dans le onPaint, tu auras ton contexte graphique et tu pourras mettre
    à jour ton graphique en fonction des infos mise à jour par les méthodes
    précedemment appelés

    Est-ce assez clair ?

    THe Monz, Toulouse

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    C'est complètement clair (tu as le chic d'être limpide ^^)

    j'ai fait mes modifications en conséquence, mais ca ne change rien hélas :/ :

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    private void VueControlePTZ_Paint(object sender, PaintEventArgs e)
            {
                pictureBox1.Image = pictureBox1.InitialImage;
                PositionCliquable posMarqueurCouleur = DefinirElementMarqueurCouleur();
     
                Graphics g = e.Graphics;
     
                //A virer
                if (posMarqueurCouleur == null)
                    posMarqueurCouleur = this.positionBoutonEtatUtilise;
     
                try
                {
                    //Si le marqueur couleur n'est aps null
                    //on est donc dans une logique d'utilisation
                    if (posMarqueurCouleur != null)
                    {
                        System.Console.WriteLine("dans UpdateVue()_1");
     
                        g.DrawImage(posMarqueurCouleur.Image, posMarqueurCouleur.CoordonneeHGImage);
     
                        System.Console.WriteLine("dans UpdateVue()_2");
     
                        //on regarde si le clic est actif => une posCourante existe
     
                        if (posCourante != null)
                        {
                            g.DrawImage(posCourante.Image, posCourante.CoordonneeHGImage);
                            System.Console.WriteLine("dans UpdateVue()_3 : on ecrit l'image supérieure");
                        }
                        System.Console.WriteLine("dans UpdateVue()_4");
                    }
                }
                catch (Exception ex) { System.Console.WriteLine(ex.Message); System.Console.WriteLine(ex.StackTrace); }
     
                g.Dispose();
            }
     
     
            public void pictureBox1_MouseUp(object sender, MouseEventArgs e)
            {
                System.Console.WriteLine("pictureBox1_MouseUp() appelée");
     
                if (e.Button == MouseButtons.Left)
                {
                    posCourante = null;
     
                    this.Invalidate();
                }
            }

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    As tu bien vérifié que tu passais dans ton paint ?

    Sinon, une solution

    Apres l'initializeComponent(), tu rajoutes

    SetStyle(ControlStyles.AllPaintingInWmPaint, true);

    Parfois ca peut aider

    Mais vérifie que le paint est appelé, car ton soucis ressemble un peu à cela

    The Monz, Toulouse

  5. #5
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    je passe bien dans mon paint, les ligens de traces apparaissent en console
    SetStyle ne m'apporte rien.

    Est ce que je dois ajouter un traitement particulier dans le InitializeComponent de mon Form de test ? par défaut j'instancie la vue, la positionne dans mon form, et point.

    Sinon, ce qui pourrait être jouable, au lieu d'essayer de redessiner une image au dessus de celle du pictureBox, ce serait generer la nouvelle image en buffer, puis définir cette nouvelle image comme image du pictureBox. Dans ce cas là comment je bufferise l'image pour dessiner dessus ?

  6. #6
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    attention, tu mets une image "Au dessus de ta pictureBox" ?

    Si c'est ca, ce que ta pictureBox écrase ce que tu fais peut-etre ?

    THe Monz, Toulouse

  7. #7
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Yep; je veux mettre une image au dessus de la picturebox, afin de modifier l'affichage.

    ma classe VueControlePTZ instancie un pictureBox sur lequel je met l'image par défaut, puis le OnPaint de VueControlePTZ doit dessiner l'image désirée par dessus le picturebox.

    Là je viens d'essayer de retirer le pictureBox : cets le UserCOntrol qui recoit l'image de fond, qui est receptif aux clics de souris, et ca marche à peu près (jai mes couleurs, mais ca donne un effet clignotement...)

    Donc ta supposition doit être juste, l'image par défaut ecrase les modifs. Comme faire pour que Graphics dessine bien au dessus du composant ?

    Merci

  8. #8
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    ce qu'il te faut faire, c'est un UserControl qui hérite de la pictureBox

    Ainsi, tu n'auras plus de soucis

    (par contre, il faut faire un override du OnPaint() de la pictureBox... si tu fais
    ainsi, tu auras quelque chose de propre

    The Monz, Toulouse

  9. #9
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Je galere sur mon picturebox hérité :

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
        public class PictureBoxControlePTZ : PictureBox
        {
            private PositionCliquable voyant = null;
            private PositionCliquable zoneActive = null;
     
            public PositionCliquable ZoneActive
            {
                get { return zoneActive; }
                set { zoneActive = value; }
            }
     
            public PositionCliquable Voyant
            {
                get { return voyant; }
                set { voyant = value; }
            }
     
            public PictureBoxControlePTZ()
            :base()
            {           
            }
     
            protected override void OnPaint(PaintEventArgs pe)
            {
                base.OnPaint(pe);
     
                this.Image = global::Projet.Properties.Resources.image_defaut;
     
                Graphics g = pe.Graphics;
                try
                {
                    //Si le marqueur couleur n'est aps null
                    //on est donc dans une logique d'utilisation
                    if (voyant != null)
                    {
                        g.DrawImage(voyant.Image, voyant.CoordonneeHGImage);
     
                        //on regarde si le clic est actif => une posCourante existe
     
                        if (zoneActive != null)
                            g.DrawImage(zoneActive.Image, zoneActive.CoordonneeHGImage);
                    }
                }
                catch (Exception ex) { System.Console.WriteLine(ex.Message); System.Console.WriteLine(ex.StackTrace); }
                g.Dispose();
            }
        }
    avec l'exception suivante :
    Le paramètre n'est pas valide.
    System.Drawing
    à System.Drawing.Graphics.GetHdc()
    à System.Drawing.BufferedGraphics.RenderInternal(HandleRef refTargetDC, BufferedGraphics buffer)
    à System.Drawing.BufferedGraphics.Render()
    à System.Windows.Forms.Control.WmPaint(Message& m)
    à System.Windows.Forms.Control.WndProc(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    à System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    à System.Windows.Forms.Applicati'Projet.vshost.exe' (Managé) : 'C:\WINDOWS\assembly\GAC_MSIL\System.Drawing.resources\2.0.0.0_fr_b03f5f7f11d50a3a\System.Drawing.resources.dll' chargé, aucun symbole chargé.
    Une exception de première chance de type 'System.ArgumentException' s'est produite dans System.Drawing.dll
    Le thread 0x944 s'est arrêté avec le code 0 (0x0).
    Le thread 0x380 s'est arrêté avec le code 0 (0x0).
    j'essaie depuis cette apres-midi de remonter l'erreur, mais je ne la comprends pas.

    Merci de l'aide

  10. #10
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    Salut

    Bon, c'est archi normal qui te plante

    En fait, comme dans ton constructeur, tu n'appelles pas : InitializeComponent();

    il n'appelle pas toute la tringlerie d'un UserControl, donc, pas de création
    des contextes d'affichages, graphiques, etc...

    Ton constructeur devrait etre comme cela normalement (au minimum)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public PictureBoxControlePTZ()
            {
                InitializeComponent();
            }
    The Monz, Toulouse

  11. #11
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2006
    Messages
    1 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 627
    Points : 2 331
    Points
    2 331
    Par défaut
    Et moi qui pensait que le fait d'appeler le constructeur parent déléguerai cette tâche, j'avais tout faux ^^

    Donc je me fais un InitializeComponent, dedans je lui donne les attributs par défaut, et yopla quoi

    Y a t-il des appels obligatoires à faire dans cette fonction ?

  12. #12
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    Non, pas d'appel obligatoire ...

    Dans la mesure ou tu override le OnPaint().. peut-etre (à vérifier ) qu'il faut
    rajouter le ligne de code sur le SetStyle(AllPaintingIn..., true) ;

    à voir

    The Monz, Toulouse

Discussions similaires

  1. Enregistrer un dessin fait avec Graphics en EPS et PDF
    Par leonidas02 dans le forum Caml
    Réponses: 2
    Dernier message: 24/12/2013, 01h57
  2. Problème avec Dispose() sur picturebox
    Par Guyome41 dans le forum VB.NET
    Réponses: 10
    Dernier message: 01/12/2012, 09h21
  3. Réponses: 0
    Dernier message: 14/11/2010, 14h59
  4. déplacer un dessin fait avec 'graphics'
    Par natha31 dans le forum ActionScript 3
    Réponses: 4
    Dernier message: 15/10/2010, 02h23
  5. Images avec paragraphe sur un côté
    Par Nicomart dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 4
    Dernier message: 04/09/2007, 12h36

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