Matt McManis Matt McManis - 1 year ago 100
C# Question

Pass ComboBox Selected Item as Method Parameter

What's the proper way to pass a ComboBox Selected Item as a Method Parameter?

Or is there even any advantage to doing this?

I have limited experience in program design and passing parameters.




Here's an example method that returns the opposite color of selected.

XAML



<ComboBox x:Name="cboColors"
HorizontalAlignment="Left"
Margin="179,82,0,0"
VerticalAlignment="Top"
Width="120"
SelectedIndex="0">
<System:String>Red</System:String>
<System:String>Orange</System:String>
<System:String>Yellow</System:String>
<System:String>Green</System:String>
<System:String>Blue</System:String>
<System:String>Purple</System:String>
</ComboBox>





C Sharp



Hardcoded

ComboBox Selected Item is set in the if statement

// Find Opposite Color
//
public String OppositeColor()
{
if ((string)cboColors.SelectedItem == "Red")
{
return "Green";
}
else if ((string)cboColors.SelectedItem == "Orange")
{
return "Blue";
}
else if ((string)cboColors.SelectedItem == "Yellow")
{
return "Purple";
}
else if ((string)cboColors.SelectedItem == "Green")
{
return "Red";
}
else if ((string)cboColors.SelectedItem == "Blue")
{
return "Orange";
}
else if ((string)cboColors.SelectedItem == "Purple")
{
return "Yellow";
}
else
{
return string.Empty;
}
}


// Display Opposite Color Button
//
private void button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(OppositeColor());
}


 

Pass Parameter

ComboBox Selected Item is set to an Object then passed to the Method

// Find Opposite Color
//
public String OppositeColor(Object color)
{
if (color.Equals("Red"))
{
return "Green";
}

...
}


// Display Opposite Color Button
//
private void button_Click(object sender, RoutedEventArgs e)
{
// Set Selected Color
Object color = cboColors.SelectedItem;

// Display
MessageBox.Show(OppositeColor(color));
}

Answer Source

WPF has bindings that can help you with this. If you create a simple helper class to represent your items in the combobox:

public class ComboItem
{
  public string Color { get; private set; }
  public string OppositeColor { get; private set; }

  public ComboItem(string color, string opposite)
  {
    Color = color;
    OppositeColor = opposite;
  }
}

And in your code behind have a collection the combobox can bind to:

private List<ComboItem> _myComboItems = new List<ComboItem>()
{
  new ComboItem("Red", "Green"),
  new ComboItem("Orange", "Blue"),
  new ComboItem("Yellow", "Purple"),
  new ComboItem("Green", "Red"),
  new ComboItem("Blue", "Orange"),
  new ComboItem("Purple", "Yellow")
};

public List<ComboItem> MyComboItems
{
  get { return _myComboItems; }
}

Implement INotifyPropertyChanged interface to event to the UI when a property in your view changes (without having to implement and dependency properties):

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName)
{
  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

And an item to set when the user makes a selection:

private ComboItem _selected = null;

public ComboItem SelectedComboItem
{ 
  get { return _selected; }
  set
  {
    _selected = value;
    OnPropertyChanged("SelectedComboItem");
  }
}

you are able to set your xaml to look like:

<ComboBox ItemsSource="{Binding MyComboItems}"
          SelectedItem="{Binding SelectedComboItem}"
          DisplayMemberPath="Color"/>

Ince this is in place, when the user presses the button (button1), your handler can do what you want it to in a few different ways:

private void button_Click(object sender, RoutedEventArgs e)
{
  MessageBox.Show(SelectedComboItem.OppositeColor);
}

which accesses the selected items property for opposite color directly, or for your want to pass parameters:

private void button_Click(object sender, RoutedEventArgs e)
{
  MessageBox.Show(GetOppositeColor(SelectedComboItem));
}

private string GetOppositeColor(ComboItem item)
{
  if (item != null)
    return item.OppositeColor;

  return "No opposite color available";
}

To set the initial selected item in the combo:

InitializeComponent();
// some other initialization code here...
SelectedComboItem = MyComboItems[0];

This setting of the property SelectedComboItem will cause the PropertyChanged event to fire (through OnPropertyChanged) which the combobo will get and adjust its selected item.

IMO keeping the types is important for readability and efficiency. Changing an value to type Object then casting back to the specific type it is or using ToString() is less efficient than keeping it as the type it always was to begin with and accessing its value, and it also makes following the code harder when types morph to Object and back again.

My code example eliminates the use of collections for pairing strings together in favor of using a class to wrap the relationship up. This enables you to utilize WPF's magic to get user interaction events (like selecting an item in a combo) and automatically having access to the object the selection represents (through the SelectedItem binding).

Hope this helps.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download