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 :

Gérer les évènements sur un UserControl


Sujet :

Windows Forms

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2006
    Messages : 35
    Points : 24
    Points
    24
    Par défaut Gérer les évènements sur un UserControl
    Salut à tous,

    Je suis entrain d'apprendre le fait de se créer des contrôles perso, mais plus particulièrement le fait de gérer leurx events. Je suis un peu bloqué et ce même en passant plusieurs heures à lire sur le web un peu partout.

    Pour me pratiquer voici ce que j'ai fait:

    Un contrôle "Matériel":

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
    public partial class Materiel : UserControl
        {      
            private int typeMateriel;
            private float xPos;
            private float yPos;
            private int lieuGeo;
     
            public Materiel(int type, float x, float y, int lieu)
            {
                InitializeComponent();
     
                this.AllowDrop = true;
     
                ImageMateriel res = new ImageMateriel();
     
                typeMateriel = type;
                xPos = x;
                yPos = y;
                lieuGeo = lieu;
     
                switch (typeMateriel)
                {
                    //Ordi
                    case 1:
                        this.pbElement.Image = ImageMateriel.dell_desktop;
                        break;
                    //Imprimante
                    case 2:
                        break;
                    //Autre
                    default:
                        this.pbElement.Image = ImageMateriel.dell_desktop;
                        break;
                }
            }
     
            public delegate void ClickedHandler();
            public event ClickedHandler Clicked;
     
            public void saveMateriel()
            {
                try
                {
                    //#TODO Saver le tout dans la BD OpenAudit
                }
                catch (Exception exc)
                {
                    throw exc;
                }
            }
            public Materiel getMateriel(string systemUUID)
            {
                Materiel ret = null;
                try
                {
                    //#TODO
     
                    //typeMateriel = type;
                    //xPos = x;
                    //yPos = y;
                    //lieuGeo = lieu;
                }
                catch (Exception exc)
                {
                    throw exc;
                }
                return ret;
            }
     
            public void Materiel_MouseDown(object sender, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    this.DoDragDrop(this.pbElement.Image, DragDropEffects.All);
                }
            }
     
            public void Materiel_MouseClick(object sender, MouseEventArgs e)
            {
                OnClicked();
            }
     
            protected virtual void OnClicked()
            {
                if (Clicked != null)
                {
                    Clicked();
                }
            }
        }
    Et mon formulaire:

    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
     
    public partial class Map : Form
        {
            public Map()
            {
                InitializeComponent();
            }
     
            private void Map_FormClosing(object sender, FormClosingEventArgs e)
            {
                Main.refMap = null;
            }
     
            private void pbMap_DragDrop(object sender, DragEventArgs e)
            {
                if (e.Data.GetDataPresent(DataFormats.Bitmap))
                {
                    //Bitmap image = (Bitmap)(e.Data.GetData(DataFormats.Bitmap));
     
                    Materiel mat = new Materiel(1, e.X, e.Y, 1);
                    mat.AllowDrop = true;
                    //mat.MouseDown += new MouseEventHandler(mat1_MouseDown);
     
                    this.Controls.Add(mat);
                    mat.Location = new Point(e.X, e.Y);
                    mat.BringToFront();
                }
            }
     
            private void pbMap_DragOver(object sender, DragEventArgs e)
            {
                e.Effect = DragDropEffects.All;
            }
     
            private void button1_Click(object sender, EventArgs e)
            {
                Materiel mat1 = new Materiel(1, 20, 20, 1);
                this.Controls.Add(mat1);
                mat1.Location = new Point(100, 100);
                mat1.AllowDrop = true;
                mat1.Clicked += new Materiel.ClickedHandler(mat1_Clicked);
                mat1.BringToFront();
            }
     
            private void mat1_Clicked()
            {
                MessageBox.Show("Hey hey!!!");
            }
        }
    Ce que je veux faire fonctionner en premier lieu est le clicked de mon contrôle. Ensuite le drag and drop sera surement trivial...

    J'imagine que cela vient de fait que j'ajoute le contrôle via le code et que la référence à l'objet n'existe plus à cause qu'il est déclaré dans un event au lien d'être public au form ?? Est-ce que je m'y prend bien?

    Merci pour le coup de main et je continue mes lectures

  2. #2
    Membre habitué Avatar de obitskater
    Profil pro
    Développeur .NET
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 132
    Points
    132
    Par défaut
    Salut, pour ce que tu souhaites faire, je ne suis pas sûr qu'il soit nécessaire de passer par un delegate (cf. ClickedHandler), c'est surtout utile pour du multi-threading si je ne m'abuse.

    donc il faut simplement que tu déclares un eventHandler public dans ton userControl.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public EventHandler _onClick;
     
    public void Materiel_MouseClick(object sender, MouseEventArgs e)
    {
                if(_onClick != null)
                {
                    _onClick(sender, e);
                }
    }
    Puis dans ta form définir ce qui va être fait quand tu clique dans ton userControl. Il vaut mieux que tu déclares ton userControl en membres global de ta form.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    private Materiel _mat1 = new Materiel(1, 1.0, 1.0, 1);
     
    private void InitEventMateriel()
    {
       _mat1._onClick += new EventHandler(Materiel_OnClick);
    }
     
    private void Materiel_OnClick(object sender, EventArgs e)
    {
       MessageBox.Show("hey hey! Ca a cliqué youpi");
    }
    J'espère que j'ai bien saisi ton problème et ai pu t'aider correctement

  3. #3
    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
    Salut,

    le pattern courant pour les event est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // on déclare dans la classe un event nommé TonEvent, du type EventHandler
    public event EventHandler TonEvent;
     
    protected void OnTonEvent()
    {
      if (TonEvent != null)
        TonEvent(this, EventArgs.Empty);
    }
     
    // ailleurs dans ton code, quand tu veux déclencher l'event :
    OnTonEvent();
    Ca, c'est le cas simple où on lève un événement sans trimballer de données. Dans les autres cas, il faut remplacer EventHandler par EventHandler<XXXEventArgs>, où XXXEventArgs est une classe dérivée d'EventArgs : c'est elle qui contient les données à transmettre.

    @obitskater : attention, les event n'ont rien à voir avec le multithreading ! Ils permettent juste à une classe d'appeler du code venant de l'extérieur.
    ಠ_ಠ

  4. #4
    Membre habitué Avatar de obitskater
    Profil pro
    Développeur .NET
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 132
    Points
    132
    Par défaut
    Citation Envoyé par Guulh Voir le message
    @obitskater : attention, les event n'ont rien à voir avec le multithreading ! Ils permettent juste à une classe d'appeler du code venant de l'extérieur.
    Quand je parlais du multi-threading, c'était concernant le cas dans lequel on utilisait des events avec des méthodes delegate

  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 obitskater Voir le message
    Quand je parlais du multi-threading, c'était concernant le cas dans lequel on utilisait des events avec des méthodes delegate
    C'est toujours le cas, puisqu'on ne peut abonner que des delegates à un event.
    Et je répète : il n'y a rien à voir entre les event et les threads. Un event (au sens que C# donne à ce mot-clé), c'est tout ce qu'il y a de plus synchrone.
    ಠ_ಠ

  6. #6
    Membre habitué Avatar de obitskater
    Profil pro
    Développeur .NET
    Inscrit en
    Février 2008
    Messages
    163
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2008
    Messages : 163
    Points : 132
    Points
    132
    Par défaut
    @Guulh : et bien merci, j'aurais agrandi ma culture aujourd'hui . Mais il est vrai que pour ma part je n'utilise les delegates que dans le cas où je veux récupérer des events d'un thread à l'autre.

    Et dans le cas d'event simple d'une form à l'autre je fais comme j'ai cité plus haut.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2006
    Messages : 35
    Points : 24
    Points
    24
    Par défaut
    Rien à faire Grrrr!

    Je ne comprends vraiment pas ce que je fais de mal. Je place le code que vous m'avez soumis gentillement, mais aucun évènement n'est lancé.

    Voici en résumé ce que ca donne:

    Fichier Materiel.cs (Qui est mon usercontrol perso):
    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
     
    public partial class Materiel : UserControl
        {      
            private int typeMateriel;
            private float xPos;
            private float yPos;
            private int lieuGeo;
     
            public Materiel(int type, float x, float y, int lieu)
            {
                InitializeComponent();
     
                this.AllowDrop = true;
     
                ImageMateriel res = new ImageMateriel();
     
                typeMateriel = type;
                xPos = x;
                yPos = y;
                lieuGeo = lieu;
     
                switch (typeMateriel)
                {
                    //Ordi
                    case 1:
                        this.pbElement.Image = ImageMateriel.dell_desktop;
                        break;
                    //Imprimante
                    case 2:
                        break;
                    //Autre
                    default:
                        this.pbElement.Image = ImageMateriel.dell_desktop;
                        break;
                }
            }
     
            public event EventHandler Clicked;
     
            public void Materiel_MouseClick(object sender, MouseEventArgs e)
            {
                OnClicked();
            }
     
            protected virtual void OnClicked()
            {
                if (Clicked != null)
                {
                    Clicked(this, EventArgs.Empty);
                }
            }
        }
    Et voici mon fichier Map.cs (Qui est mon form dans lequel je veux ajouter dynamiquement du materiel):

    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
     
        public partial class Map : Form
        {
            private Materiel systemActif;
     
            public Map()
            {
                InitializeComponent();
            }
     
            //Bouton de test qui ajoute dynamiquement un materiel sur la map
            private void button1_Click(object sender, EventArgs e)
            {
                systemActif = new Materiel(1, 20, 20, 1);
                systemActif.Name = "test1";
                this.Controls.Add(systemActif);
                systemActif.Clicked += new EventHandler(systemActif_Clicked);
                systemActif.AllowDrop = true;
                systemActif.Location = new Point(100, 100);
                systemActif.BringToFront();
            }
            private void systemActif_Clicked(object sender, EventArgs e)
            {
                MessageBox.Show("Hey hey!!!");
            }
        }
    Est-ce que j'ai oublié un bout de code en quelque part?

    Merci pour l'aide et désolé pour le délais de réponse Un autre projet m'arrive de front

  8. #8
    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
    Execute ton code en mode debug et mets des points d'arret un peu partout. Tu verras bien dans quelles methodes tu passes.
    Est-ce que la methode Materiel_MouseClick de ton user Control est bien abonnee a l'evenement MouseClick ?
    ಠ_ಠ

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2006
    Messages : 35
    Points : 24
    Points
    24
    Par défaut
    Ohhhh! Je viens de saisir mon erreur...

    Je croyais qu'en affectant un event à mon user Control Materiel comme tel, l'event serait lancé peu importe où je clickerais sur celui-ci, ce qui est faux.

    En lancant l'event sur toutes mes composantes de mon userControl, là ca fonctionne. Dans mon cas, ce n'est pas trop contraignant, mais il doit certainement y avoir une facon d'affecter un event à l'ensemble des composantes d'un contrôle en une ligne?

    Merci pour l'info

  10. #10
    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
    Je sais plus s'il est possible à un contrôle conteneur de choper les événements de souris quand ils ont lieu dans l'un de ses contrôles fils.
    Et pour ton one-liner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    foreach(Control c in this.Controls)
      c.MouseClick += this.Materiel_MouseClick;
    ಠ_ಠ

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Septembre 2006
    Messages : 35
    Points : 24
    Points
    24
    Par défaut
    Merci beaucoup à vous 2 pour votre aide

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 30/05/2012, 10h42
  2. [OL-2007] Gérer les événements sur les dossiers
    Par phertzog dans le forum Outlook
    Réponses: 0
    Dernier message: 21/05/2009, 01h00
  3. Gérer les évènements lors d'un click sur les JButtons
    Par othman22222 dans le forum Composants
    Réponses: 1
    Dernier message: 22/12/2008, 16h08
  4. Réponses: 5
    Dernier message: 25/07/2005, 09h29
  5. Gérer les clics sur les boutons
    Par cyberlewis dans le forum Windows
    Réponses: 4
    Dernier message: 08/02/2004, 15h34

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