المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : An elegant binding solution to getting the user to choose a COM port



C# Programming
05-28-2009, 09:11 PM
Hi Everyone,

I have been trying to figure out an elegant way to get the result I want to something that must be a very common issue; getting the user to choose the COM port from a list. I can't find a neat solution out there, I thought maybe someone here would have a suggestion.

The setup is a new WPF window is spawned that just contains a ComboBox (for now) for choosing the COM port, this needs to be double bound. The first binding is to get the array of strings from the SerialPort.GetPortNames() static method, these will be the items in the list.

// This is how I currently do it
// Create the ObservableCollection supporting ArrayList and fill it
portList = new System.Collections.ArrayList(16);
foreach (string port in System.IO.Ports.SerialPort.GetPortNames())
{
portList.Add(port);
}
comPortListBox.ItemsSource = portList;

The next binding is to SelectedItem which should get and set the value in the properties of the application. When the window is closed, the properties are saved.

Properties.Settings.Default.SerialInterfaceComPort // the value string
Properties.Settings.Default.Save();

I have included how I am currently making it work below, there is a lot of code tho and it has some bugs to do with the properties value returning null sometimes.

I should point out that in the example the baud rate list works perfectly as it is based on a list of values in the XAML and I don't have to create it from a string array. Although, if anyone knows how to get a list of valid port speeds for a particular port that could be made pretty fancy.

Any suggestions on how to make this nice and elegant with better data binding would be great!

Thanks

Ed
public SerialSettingsWindow()
{
InitializeComponent();

// Create the ObservableCollection supporting ArrayList and fill it
portList = new System.Collections.ArrayList(16);
foreach (string port in System.IO.Ports.SerialPort.GetPortNames())
{
portList.Add(port);
}

// Record the current values of the properties in case we decide to cancel.
// This is only important when the data binding is working as the properties
// gets updated automatically so it has no impact on the ComPortList at the moment.
tempComPort = Properties.Settings.Default.SerialInterfaceComPort;
tempBaudRate = Properties.Settings.Default.SerialInterfaceBaudRate;

// Set the ItemSource and get the SelectedIndex by searching the ArrayList
comPortListBox.ItemsSource = portList;
int portIndex = portList.BinarySearch(Properties.Settings.Default.SerialInterfaceComPort);
if (portIndex >= 0 && portIndex < comPortListBox.Items.Count)
{
comPortListBox.SelectedIndex = portIndex;
}
else
{
comPortListBox.SelectedIndex = -1;
}

// BaudRateList binds directly to the application properties file
baudRateListBox.DataContext = Properties.Settings.Default;
}


private void cancelButton_Click(object sender, RoutedEventArgs e)
{
// Reset the selected values
Properties.Settings.Default.SerialInterfaceComPort = tempComPort;
Properties.Settings.Default.SerialInterfaceBaudRate = tempBaudRate;
Properties.Settings.Default.Save();
this.Close();
}

private void doneButton_Click(object sender, RoutedEventArgs e)
{
// Manually update the properties value for the ComPort and Save
Properties.Settings.Default.SerialInterfaceComPort = comPortListBox.SelectionBoxItem.ToString();
Properties.Settings.Default.Save();
this.Close();
}
}