Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Understanding SelectedValue, SelectedValuePath, SelectedItem & DisplayMemberPath + Demo

5.00/5 (22 votes)
21 Oct 2013CPOL4 min read 111.6K   2.7K  
Sorting out the confusion about these properties, and providing a demo app for them

The project was built using VS2012 and targeting .NET 4.

Table of Contents

Introduction

I've seen this question pop around, and wanted to have a 1 stop reference to solve the issue for people trying to figure it out.

Fast and Dirty -> The Screenshot

They say a picture is worth a 1000 words, so here's a picture:

I say a demo is worth a 1000 pictures, so feel free to download the code and play with it yourself.

Extra Reading ->Verbal Explanation

This is not a new topic, as you can easily see if you'll look here, here, here or on the official MSDN page here. (Do note that on the official MSDN (at the time of writing this), 0 out of 4 rated it helpful).

SelectedItem: This will return the currently selected item in the list/combobox/container. This is an Object as you can see (since my list holds objects). If your List/Combobox/etc. contains a list of strings, it'll be a string. If it contains ints, it'll be an int.

SelectedValuePath: Setting this will make the property SelectedValue return the value of the property you have selected here. In our example, selecting "ShapeColor" will make the SelectedValue return only the color, and not the whole shape object.

Note: You set the property name as a string here. Look at the example in the demo code below for code.

SelectedValue: If you want only a part of an object, set the above property, and you'll get the value of that property here. Note that if SelectedValuePath is not used, this is the same as using SelectedItem.

DisplayMemberPath: Setting this to a property of an object, will cause the GUI to show that property when the class is selected instead of seeing the Class name or your Class ToString()method (which should always be provided. Look at Item 5, Chapter 1 in this book's ToC  or scroll down and read the whole thing :).

Using the Code

I wanted to keep this as simple and short as can be, while delivering enough punch to be interesting. I use a simple XAML file with some Code Behind, and it all clocks in at some 200 lines of code (including spaces and some comments).

MainWindow.xaml

Holds a DockPanel with a footer at the bottom and a StackPanel that will fill the window (last child by default does this).

Since I'm not using MVVM in this example, I'm binding things together by giving the Window a name, and then referring to this name in the Binding ElementName. The path will point to the matching Property on the Code Behind file.

XML
Window x:Class="SelectedValue_and_SelectedItem.MainWindow"
	... Name="SelectionFun" >
XML
<ListBox Name="SourceListBox"
   ItemsSource="{ Binding ElementName=SelectionFun, Path=ShapeCollection}" />

This covers the first part, creating and binding the objects to our list, so you can select a shape.

The second area holds a couple of ComboBoxes where you can choose the properties you'll want to bind/see, and some labels that will show you what is actually selected. I've also binded part of the grid to the shape's color to have some extra visual feedback.

The ComboBoxes look like this:

XML
<ComboBox	...
	ItemsSource="{ Binding  ElementName=SelectionFun, Path=PropertiesList}" 
	SelectionChanged="DisplayMemberPathCmbx_SelectionChanged" 	/> 

The labels are straight forward, so let's move along.

MainWindow.xaml.cs - The Code Behind

The structure I'm using for my objects is a dummy MyShape that looks like this:

C#
public class MyShape
{
    public string ShapeType  { get; set; }
    public string ShapeColor { get; set; }
    public int    ShapeSides { get; set; }
}  

A method called GetShapesList() will populate our list of shapes with objects like:

C#
return new ObservableCollection<MyShape> {	
    new MyShape{ShapeType = "Circle",    ShapeColor = "Blue",	ShapeSides = 0 },
    new MyShape{ShapeType = "Triangle",  ShapeColor = "Yellow",	ShapeSides = 3 },  ... } 

(While the sides are the actual shape's sides, the colors are just random colors I've added.)

Things get interesting when we get to the PropertiesList, which is populated like this:

C#
private static ObservableCollection<PropertyObject> GetPropertiesList()
{
  ObservableCollection<PropertyObject> return_collection = 
                               new ObservableCollection<PropertyObject> 
	{ new PropertyObject {PropertyName = "", PropertyType = "Reset to default"} };
 
  var propertiesInfos = typeof(MyShape).GetProperties();
  
  foreach (var propertyInfo in propertiesInfos)
  {
	return_collection.Add(new PropertyObject 
	{ PropertyName = propertyInfo.Name, 
	  PropertyType = propertyInfo.PropertyType.Name 
	});
  }
 
  return return_collection;
} 

The PropertyObject is a simple class to hold the Name and the Type of the property we're dealing with (both are strings).

C#
public class PropertyObject
{
  public string PropertyName { get; set; }
  public string PropertyType { get; set; }
} 

First, we'll add an empty one, so when selected, it will "reset" the binding to the default.

We'll then use reflection to find all the properties on the MyShape class so we can select them from the ComboBox. Feel free to add more properties, or generalize this method to take a Class as an argument, and then just pass your own custom Class to see it in action.

The SelectionChanged events simply set the ListBox source properties according to what is selected (we called it SourceListBox in the XAML) . For example:

C#
private void DisplayMemberPathCmbx_SelectionChanged
(object sender, SelectionChangedEventArgs e) {
  // Get the value
  ComboBox cmbx = (ComboBox)sender;
  PropertyObject prop_ob = ((PropertyObject)cmbx.SelectedItem);
  string name = prop_ob.PropertyName;

  // Actual setting happens here
  SourceListBox.DisplayMemberPath = name;
} 

That's it! Download the code and give it a spin to see it in action. :)

Points of Interest

I'm usually tending toward MVVM these days, but I wanted to keep the code brief, so I've opted for the code behind approach.

Note the use of reflection to dynamically get the properties and their type, and the way we bind the XAML to our properties with the use of names.

History

  • 21st October, 2013: Initial release

Feel free to leave a comment, feedback and/or ask any question.

License

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