Refresh available ports

We are working on a instrument using the System.IO.Ports library to connect to a COM port on windows.

Everything is working fine, but we can’t get OpenTAP to update the connected devices without restarting the whole program.

The behaviour I would like to see it that when someone clicks on the select box with the list of devices the list gets updated or, even better, catch a event when the connected devices change. So the user always sees a accurate list of available devices to choose from. I tried to use the get methods from the public List<> as wel as the public property which holds the current selected COM port. But with no success.

private List<string> m_AvailablePorts;
public List<string> mAvailablePorts
{
    get {
        m_AvailablePorts = new List<string>( SerialPort.GetPortNames());
        return m_AvailablePorts;
    }
    private set
    {  m_AvailablePorts = value;  }
}
[Display(Name: "COM Port", Group: "Connection", Order: 1.1)]
[AvailableValues( nameof( mAvailablePorts ))]
public string mComPort {
    get {
        m_AvailablePorts = new List<string>( SerialPort.GetPortNames());
        return mComPort;
    }
    set{ mComPort = value; } 
}

What would be the best solution to get a accurate list of currently connected COM port devices?

I wouldn’t recommend updating available values from within the getter of mComPort.

I usually structure things as seen below, and I get updated available values every time I click the select button. If it’s not working for you, can you verify that SerialPort.GetPortNames() is returning what you expect?

public List<string> mAvailablePorts
{
    get {
        return new List<string>( SerialPort.GetPortNames());
    }
}

[Display(Name: "COM Port", Group: "Connection", Order: 1.1)]
[AvailableValues( nameof( mAvailablePorts ))]
public string mComPort {get;set;}
1 Like

Thanks for your reply.

I tried you solution and the list is updated while the OpenTAP is running but unfortunately it does not update when I click the dropdown. It does update when opening the instrument menu, and changing the value (or any other value in the instrument). And the get function is called 5 times, which seems a little unnecessary, but I think there’s nothing we can do about that (except creating a debounce).

Any chance you know another solution?

It may be a bit simplistic, but I’d recommend creating a button in the UI to update the values. This way the user knows what to expect and you don’t create performance issues.

[Display(/*...*/)]
[Browsable(true)]
public void RefreshAvailablePorts(){
   mAvailablePorts = new List<string>( SerialPort.GetPortNames());
}

That’s a great idea. However, it will not call the getter to update the list in the UI.

I have done some more digging and found out even when forcefully updating the list using a timer the showed values in the UI will not update. Only when the menu is reloaded (by opening it) or a value is changed new values show. So it seems OpenTAP creates a complete copy of the class to display the menu and only gets new values when changes are made using the interface.

Ah you are right, button click does not automatically ensure a gui update. This seems like a mistake.

You can force it by calling ValidatingObject.OnPropertyChanged (so this should work on your object as well.) e.g:

[Display(/*...*/)]
[Browsable(true)]
public void RefreshAvailablePorts(){
   mAvailablePorts = new List<string>( SerialPort.GetPortNames());
 // force the GUI to reload settings values.
  OnPropertyChanged(nameof(mAvailablePorts));
}

Be a bit careful with OnPropertyChanged. It can affect UI performance if called too often.

1 Like

This works, thank you!

1 Like