none
Modification d'une proprieté dans une Windows Forms depuis un thread RRS feed

  • Question

  • Bonjour, j'ai créé une application Windows Forms et qu'en je clique sur un bouton je lance un thread qui gére une communication sur le port lpt de la machine. Mais je voudrais que lorsque se thread a fini il réactive le bouton que j'ai préalablement désactivé lorsqu'on a cliqué dessu.

    A l'heure actuelle quand le thread veut modifier la proprieté Enabled du bouton l'application génère une exception System.InvalidOperationException.

     

    Comment puis je palié à ce probleme ?

     

    Merci d'avance.

    Litoon

    dimanche 27 avril 2008 22:10

Réponses

  • Voila comment j'ai fait, j'ai nettoye le code de tout ce qui sert a rien juste pour montrer l'exemple si quelqu'un en a besoin.

     

    namespace Amenage20 {

    public ref class Form1 : public System::Windows::Forms::Form

    {

     

    private: Thread^ Autoavance;

    private: Thread^ Change;

    private: delegate void ChangeButton();

     

     

    private: System::Void Start_Click(System:Surprisebject^ sender, System::EventArgs^ e)

    {

    Autoavance = gcnew Thread(gcnew ThreadStart(this, &Form1::ThreadAuto));

    Autoavance->Start();

    this->Start->Enabled = false;

    }

     

    private: void ThreadAuto ()

    {

    //.....code utilisateur.....//

    this->Invoke(gcnew ChangeButton(this,&Form1::MethodeEnabled));

    }

     

    private: void MethodeEnabled()

    {

    this->Start->Enabled = true;

    }

    };

    }

     

    Merci encore les gars j'ai passé la journée dessu et trouvé un exemple en C# que j'ai adapté.

     

    Voici les deux lien qui m'ont servi

    http://www.csharpfr.com/code.aspx?ID=29068

    http://www.csharpfr.com/tutorial.aspx?id=174

     

    ++

     

     

     

    jeudi 1 mai 2008 19:49

Toutes les réponses

  • Bonjour,

     

    Il n'est pas possible de modifier les propriétés des contrôles depuis un Thread autre que celui du thread d'affichage (principal).

    Il faut pour cela utiliser la méthode publique Invoke des contrôles qui permet de déclencher une méthode dans le Thread d'affichage.

     

    Cordialement

     

    lundi 28 avril 2008 07:07
    Modérateur
  • Bonjour,

    Une autre possibilité que celle proposée par Gilles est d'utiliser un BackgroundWorker pour votre traitement asynchrone et de mettre le code de réactivation du bouton dans un handler sur l'évènement RunWorkerCompleted.

    Tous les handlers sur les évènements du BackgroundWorker sont appelés dans leur context d'origine ce qui vous permet de travailler comme vous en avez l'habitude en synchrone.

    lundi 28 avril 2008 08:14
  • Bonjour,

    Une autre possibilité est d'utilisé un délégué asynchrone.

    Le délégué asynchrone te fera un code plus compact., bien que le Backgroundworker réponde parfaitement au besoin.

     

    Des exercices du coach C++ en cours de publication présente ces différentes approches.

     

    Cordialement

    Michel4CE

     

    mardi 29 avril 2008 11:34
  • Merci pour vos reponses je vais regardé tout sa mais vue que j'ai pas fait de programmation depuis mon école il y a 6 ans je rame un peu lol et que j'ai appris sur linux alors j'apprend a utilisé le rad et tout ce que je n'avais pas vue jusque la.

     

    Cordialement.

    Litoon

     

    mardi 29 avril 2008 11:44
  •  

    Bonjour, j'ai regarde un peu les propositions que vous m'avez faites mais soit je sais pas faire (mon avis) ou cela ne correspond pas a ce que je cherche à faire. J'explique exactement ce que je cherche a faire:

    Dans la form il y a 2 boutons 1 start et 1 stop, le start lance une communication pour controle une machine via le lpt du pc. L'utilisateur doit a tout moment pouvoir appuyez sur stop ou ARu de l'application pour arrete le deplacement de la machine et la remettre en etat repos, pour cela mon choix d'un thread qui me permet d'appele abort dans mon processu principale et de tout arrete tres rapidement. Lorsque je lance le thread je desactive le bouton start pour ne pas que l'utilisateur puisse réappuiez dessu et quand le thread a fini il le reactive pour eventuellement pouvoir relance un cycle.  

     

    Cordialement Merci d'avance de votre aide.

     

    jeudi 1 mai 2008 15:28
  • Voila comment j'ai fait, j'ai nettoye le code de tout ce qui sert a rien juste pour montrer l'exemple si quelqu'un en a besoin.

     

    namespace Amenage20 {

    public ref class Form1 : public System::Windows::Forms::Form

    {

     

    private: Thread^ Autoavance;

    private: Thread^ Change;

    private: delegate void ChangeButton();

     

     

    private: System::Void Start_Click(System:Surprisebject^ sender, System::EventArgs^ e)

    {

    Autoavance = gcnew Thread(gcnew ThreadStart(this, &Form1::ThreadAuto));

    Autoavance->Start();

    this->Start->Enabled = false;

    }

     

    private: void ThreadAuto ()

    {

    //.....code utilisateur.....//

    this->Invoke(gcnew ChangeButton(this,&Form1::MethodeEnabled));

    }

     

    private: void MethodeEnabled()

    {

    this->Start->Enabled = true;

    }

    };

    }

     

    Merci encore les gars j'ai passé la journée dessu et trouvé un exemple en C# que j'ai adapté.

     

    Voici les deux lien qui m'ont servi

    http://www.csharpfr.com/code.aspx?ID=29068

    http://www.csharpfr.com/tutorial.aspx?id=174

     

    ++

     

     

     

    jeudi 1 mai 2008 19:49