2011-07-11 2 views
0

Je tente d'écrire un programme qui utilise une zone de liste déroulante pour afficher actuellement connectés ports COM obtenus à partir de la méthode suivante:Ajout/Suppression des ports COM à partir d'une zone de liste déroulante en C#

System.IO.Ports.SerialPort.GetPortNames() 

L'idée est d'initialiser un fil qui vérifie les ports COM actuellement disponibles chaque seconde et met à jour le ComboBox en conséquence. Malgré mes meilleurs efforts, je ne peux pas le faire fonctionner.

Le code pour mettre à jour le contenu de ComboBox est la suivante:

private void Form1_Load(object sender, EventArgs e) 
    { 
     availPorts = new BindingList<String>(); 

     Thread t = new Thread(new ThreadStart(update)); 
     t.Start(); 
    } 

    private void update() 
    { 
     this.comboBox1.DataSource = availPorts; 

     while (true) 
     { 
      Console.WriteLine("CHECK"); 

      foreach (String port in System.IO.Ports.SerialPort.GetPortNames()) 
      { 
       if (!availPorts.Contains(port)) 
       { 
        Console.WriteLine("FOUND"); 
        availPorts.Add(port); 
       } 
      } 

      Thread.Sleep(1000); 
     } 
    } 

je peux voir les messages de la console que les ports se trouvent, mais le ComboBox reste vide. Toute aide serait grandement appréciée.

+0

Avez-vous lié availPorts avec ComboBox? – longbkit

+0

'this.comboBox1.DataSource = availPorts;' N'est-ce pas la déclaration de liaison? – isometrik

+0

Pas lorsque vous en créez un nouveau dans l'événement Load. –

Répondre

0

Le ComboBox est pas mis à jour parce que le fil conçu pour exécuter le procédé de mise à jour tente de mettre à jour un contrôle visuel appartenant à un autre fil. Dans la plupart des cas, cela entraînerait une erreur, mais ce n'est pas le cas ici.

J'ai résolu ce problème en créant d'abord une méthode, distincte de la mise à jour, qui gère uniquement l'ajout de noms de port COM à la source de données. Au sein de cette méthode est une instruction if vérifiant si un Invoke est nécessaire:

private void addPort(String port) 
    { 
     if (this.InvokeRequired) 
     { 
      this.Invoke(new addPortDelegate(addPort), port); 
     } 
     else 
     { 
      availablePorts.Add(port); 
      Console.WriteLine("FOUND"); 
     } 
    } 

Si un Invoke est nécessaire, la méthode est appelée dans le thread correct par un délégué:

private delegate void addPortDelegate(String s); 

Cela provoque le ComboBox être mis à jour lorsque de nouveaux ports COM sont détectés par l'exécution continue de la méthode de mise à jour. Une méthode similaire peut être écrite pour supprimer les ports COM qui ont été déconnectés du système. N'oubliez pas de terminer le fil lorsque le formulaire se ferme, sinon il tournera à l'infini.

0

Essayez de modifier le code comme ceci.

BindingList<String> availPorts = new BindingList<String>(); 
AutoResetEvent autoResetEvent = new AutoResetEvent(false); 
private void Form1_Load(object sender, EventArgs e) 
{ 

    Thread t = new Thread(new ThreadStart(update)); 
    t.Start(); 
    autoResetEvent.WaitOne(); 
    this.comboBox1.DataSource = availPorts; 
} 

private void update() 
{ 
    //this.comboBox1.DataSource = availPorts; 

    while (true) 
    { 
     Console.WriteLine("CHECK"); 

     foreach (String port in System.IO.Ports.SerialPort.GetPortNames()) 
     { 
      if (!availPorts.Contains(port)) 
      { 
       Console.WriteLine("FOUND"); 
       availPorts.Add(port); 
      } 
     } 

     autoResetEvent.Set(); 
    } 
} 
+0

Si j'utilise ce code avec l'ajout de l'instruction sleep, cela ne fonctionne toujours pas comme je le souhaite. Si je commence le débogage avec un port COM déjà connecté alors il sera détecté et affiché comme un élément dans la ComboBox, cependant si je débute le débogage sans ports COM connectés et que je brancherai un, le message de la console affichera "FOUND" mais pas L'élément apparaît dans le ComboBox. – isometrik

+0

Je n'ai pas eu le problème :( – Anuraj

Questions connexes