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

C# Discussion :

Event et control non Windows Forms


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Par défaut Event et control non Windows Forms
    Bonjour à tous,

    J'ai créé un control (base Component) qui doit générer de temps en temps
    un Event pour informer de l'état d'avancement d'une tache. Il s'agit d'un
    message (string) mis à jour au cours du temps.
    Lorsque je place ce control sur une Form, j'ai accès au gestionnaire
    d'event pour ajouter du code dans ma Form, sans soucis.

    Problème : lorsque je souhaite mettre à jour un Label avec le message
    reçu par l'intermédiaire de l'event, j'ai un message du genre :

    Opération inter-threads non valide : le contrôle 'm_ShowLogBtn' a fait l'objet d'un accès à partir d'un thread autre que celui sur lequel il a été créé.
    Je cherche à mettre à jour la propriété Text d'un Button.

    Quelqu'un a-t-il une solution à mon problème ?

    Merci par avance

    Philippe

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 135
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    this.BeginInvoke((Action)()=>{
    this.myLabel.Text=valeur;
    });
    (en supposant que "this" fait référence à ta form)

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    si c'est un component ce n'est pas un control !

    il est impossible de modifier un control depuis un thread autre que son créateur, il faut alors demander au controle d'appeler une méthode (anonyme comme icareo le propose ou non) pour que le thread principal s'en occupe

    begininvoke est asynchrone, invoke est synchrone
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Par défaut
    merci icareo pour ta réponse. Malheureusement, je ne souhaite pas
    que le destinataire de mon control utilise PInvoke. Je souhaite copier
    le comportement d'un Timer.

    Voici des éléments supplémentaires pour la réflexion

    Code de mon control :

    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
    [Description("Component for backups"), DefaultEvent("Change")]
      public class BackupCpnt : Component
      {
     
        public class BkpCpntArgs : System.EventArgs
        {
     
          private string message;
     
          public BkpCpntArgs(string m)
          {
            this.message = m;
          }
     
          public string Message
          {
            get { return message; }
          }
        }
     
        public delegate void ChangingHandler(Object sender, BkpCpntArgs e);
     
        // event declaration 
        [Category("Configuration")]
        public event ChangingHandler Change; 
     
        ...
     
        private void OnCountingEvent()
        {
          m_LastMessage = "Counting...";
     
          // fire event
          Change(this, new BkpCpntArgs(m_LastMessage));
     
        }
    Code de la Form :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    private void backupCpnt1_Change(object sender, BkpCpntArgs e)
    {
        // ça plante ici !!!
        m_ShowLogBtn.Text = e.Message;
    }

  5. #5
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Par défaut
    Pol63 :

    Si je change de classe de base
    de Component -> Control, ça devrait résoudre mon souci ?

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    un invoke n'a rien à avoir avec un Pinvoke

    si tu veux que le destinataire n'ai pas à faire d'invoke, c'est à toi de le faire avant de déclencher ton évènement
    pour ca il y a une bidouille : system.windows.forms.application.openforms(0).invokerequired / invoke
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 135
    Par défaut
    Ce n'est pas un P/Invoke... c'est une exécution déportée à un autre thread.
    Et je vois mal comment tu peux faire autrement... comme le fait remarquer pol63 :

    Tu ne peux modifier l'interface utilisateur que depuis le thread STA sur lequel elle a été créée.

    Or visiblement, ta fonction "backupCpnt1_Chang" est appelée depuis un autre thread que le STA sur lequel a été créé ta form (ton thread principal, à priori).

    Donc d'une manière ou d'une autre, il va falloir dire à ton UI d'exécuter du code !

    Invoke et BeginInvoke sont là pour ça.
    Il y a d'autres moyens, mais c'est plus hardu et surtout... ça revient au même.

  8. #8
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2011
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 79
    Par défaut
    OK, je commence à saisir le problème.

    J'essaye de faire l'analogie avec Timer

    En regardant un peu à droite à gauche, Timer est un Component, membre
    de System.Windows.Forms. Il génère donc des event (toutes les x millisec) et
    on peut modifier un control d'une Form grace à cet event.

    Quelle propriété/caractéristique fait que cela marche avec Timer ?

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    135
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 135
    Par défaut
    Tu utilises System.Windows.Forms.Timer qui fait les invokes pour toi.

    Il y a une autre classe timer avec laquelle ça ne marcherait pas :

    System.Threading.Timer

    Ca a l'avantage d'être un poil plus performant... mais pas question de modifier l'UI !

  10. #10
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    à piori il doit utiliser invokerequired et invoke, comme on te l'a conseillé ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

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

Discussions similaires

  1. Comment lier user controle au windows form ?
    Par genius4evers dans le forum C#
    Réponses: 2
    Dernier message: 17/11/2011, 09h22
  2. Hosting .NET Windows Forms Controls in IE
    Par AntonioMath dans le forum Windows Forms
    Réponses: 0
    Dernier message: 21/04/2009, 21h18
  3. Login control dans Windows Forms
    Par débutant_C# dans le forum Windows Forms
    Réponses: 4
    Dernier message: 19/05/2008, 15h32
  4. [VB.NET] Type non défini quand j'appelle un Windows Form ?
    Par beegees dans le forum Windows Forms
    Réponses: 4
    Dernier message: 12/06/2006, 11h12

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