Click here to Skip to main content
15,868,082 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
Hello.

I'm creating a windows program (Visual Studio - C#) to communicate with AVR MCU using serial port. I want to show available serial ports in a ListBox (or combobox) and update the list immediately when a new device is available or a device is disconnected.

Currently I use a "Refresh" button to do that but I want it to be updated automatically.

Also I have a "Connect" button. I want it to be disabled when there isn't any available port and be enabled when some ports are available and user selected one. Currently "Refresh" button updates its state.

I already searched the google but didn't find any "understandable" thing! I'm not very familiar with C# and generally OOP languages (I just wrote C for about 3 years).

What I have tried:

Tried data binding but it didn't work. I think I used it incorrectly.
Current code (simplified):
MainWindow.xaml:
XML
<ListBox x:Name="portList" Grid.Row="1" Margin="0,5"/>
<Button x:Name="refreshButton" Grid.Row="2" Content="Refresh" HorizontalAlignment="Left" Width="75" Click="RefreshButton_Click"/>
<Button x:Name="connectButton" Grid.Row="2" Content="Connect" HorizontalAlignment="Right" Width="75" Click="ConnectButton_Click"/>

ManiWindow.xaml.cs:
C#
public MainWindow()
{
	InitializeComponent();
	Port_check();
}
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
	Port_check();
}
private void ConnectButton_Click(object sender, RoutedEventArgs e)
{
	if (!connected)
	{
		Ser_Connect();
	}
	else
	{
		Ser_Disconnect();
	}
}

Serial.cs:
C#
public readonly SerialPort serialPort = new SerialPort
{
	BaudRate = 38400,
	ReadBufferSize = 8,
	WriteTimeout = 500,
	ReadTimeout = 5000
};
public static bool connected = false;
public void Port_check()
{
	string[] ports = SerialPort.GetPortNames();
	if (ports.Length != 0)
	{
		Ports_available(ports);
	}
	else
	{
		No_ports_available();
	}
}
private void Ports_available(string[] ports)
{
	portList.Items.Clear();
	foreach (string port in ports)
	{
		portList.Items.Add(port);
	}
	portList.IsEnabled = true;
	portList.SelectedIndex = 0;
	connectButton.IsEnabled = true;
}
private void No_ports_available()
{
	portList.Items.Clear();
	portList.IsEnabled = false;
	connectButton.IsEnabled = false;
}
public void Ser_Connect()
{
	//connection codes
}
public void Ser_Disconnect()
{
	if (serialPort.IsOpen)
	{
		serialPort.DtrEnable = false;
		serialPort.Close();
	}
	connectButton.Content = "Connect";
	portList.IsEnabled = true;
	refreshButton.IsEnabled = true;
	connected = false;
	Port_check();
}
Posted
Updated 7-Jul-22 21:05pm
v2
Comments
CHill60 2-Oct-19 11:17am    
"I think I used it incorrectly" … for us to judge that we need to see your code!
Richard MacCutchan 3-Oct-19 4:00am    
Have you used the debugger to check if you actually get any items to add to your list?
AmirSina Mashayekh 3-Oct-19 4:02am    
The above code works perfectly but I want to get rid of "Refresh" button.
Richard MacCutchan 3-Oct-19 4:47am    
Why do you need it?
AmirSina Mashayekh 4-Oct-19 6:28am    
1- to learn more about c#, wpf and ...
2- to make my app better! :)

Wel... Start here: Ready-to-use serial port enumeration list box[^]

For further details, please see: SerialPort.GetPortNames Method (System.IO.Ports) | Microsoft Docs[^]

[EDIT]
There's no guarantee that SerialPort.GetPortNames method will return the names of ports. But, there's work-around. See:
C#
void Main()
{
	
	List<SerialPortInfo> ports = null;
	string qry = "SELECT * FROM Win32_PnPEntity WHERE Caption like '%COM%'";
	//or:
	//qry = "SELECT * FROM Win32_SerialPort";
	using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\CIMV2", qry))
	{
		ports = searcher.Get().Cast<ManagementBaseObject>()	
			.Select(sp => new SerialPortInfo ((string)sp["DeviceID"], (string)sp["Caption"])) 
			.ToList() ;
	}
	foreach(SerialPortInfo mp in ports)
	{
		Console.WriteLine("{0} - {1}", mp.ID, mp.Name);
	}
	
}

// Define other methods and classes here
public class SerialPortInfo
{	
	public SerialPortInfo(string _id, string _name)
	{
		ID = _id;
		Name = _name;
	}
	
	public string ID = "";
	public string Name = "";
	
}
 
Share this answer
 
v3
public List<serialportsettingsmodel> getCommPorts()
{
List<serialportsettingsmodel> devices = new List<serialportsettingsmodel>();

string[] ports = SerialPort.GetPortNames();


foreach (string portName in ports)
{
SerialPort _serialPort1 = new SerialPort(portName);
if (_serialPort1 != null && !_serialPort1.)
{
devices.Add(new SerialPortSettingsModel()
{
DeviceID = portName,
Description = portName,
DeviceInfo = portName
});
}
}
return devices;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900