Click here to Skip to main content
15,882,315 members
Articles / Desktop Programming / WPF
Tip/Trick

Very Friendly Enum Binding In WPF

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
11 Jan 2016CPOL3 min read 27.7K   13   8
A super simple method for listing Enum members in WPF using databinding

Introduction

Providing users a selectable list of an enumeration in a UI is common sense, when you need your users to select an element of predefined qualities. However, the enumeration has to be displayed in a user friendly way. It turns out, there's a very simple way to do this, without using any custom methods, reflection, value converters, data templates or what not.

Background

I'm only a beginner in C#, and when I need any kind of functionality, I turn to CodeProject to see what the masters advise. When I needed a friendly way to list an enumeration, I came across Sacha Barber's article on CodeProject. Since I'm mainly a JavaScript programmer and just a beginner to both C# and WPF, the amount of code just needed to show a simple list seemed way too much, and frankly I didn't understand half of the code! The alternative method linked in his article didn't fare better.

Using the Code

To list any kind of user selectable enumeration in your UI, in a user friendly way, there are only, and only 4 simple steps:

  1. Define your enum normally as you would in a public class.
  2. Prepare a dictionary with your enum members as key and their descriptions as value.  Note: In the value part, you can point to strings in your .resx file if you are planning on translations, just as you would do for any string that needs to be translated.
  3. Expose the dictionary and an enum selection in your view model for consumption by your UI.
  4. Bind to your dictionary in your XAML in a combobox, display just the value, and select just the keys.

I frankly have no idea why it has to be any more complex than this. Here's step 1 and 2:

C#
public static class Definitions
{
  public enum nation
    {
      tr, fr, us, gb, gr
    }

public static Dictionary<nation, string> NationEnumDictionary = new Dictionary<nation, string>()
    {
      { nation.tr , "Turkish" },
      { nation.fr , "French" },
      { nation.us , "US citizen" },
      { nation.gb , "British" },
      { nation.gr , "Greek" }
    };
}

Here's step 3, in your view model:

C#
public Dictionary<Definitions.nation, string> NationalityList
{
  get { return Definitions.NationEnumDictionary; }
}

public Definitions.nation SelectedNationality { get; set;}

And here's step 4, in your XAML code:

XML
<ComboBox ItemsSource="{Binding NationalityList}" DisplayMemberPath="Value" 
SelectedValuePath="Key" SelectedValue="{Binding SelectedNationality}" 
Height="22" Width="80" />

The result is a combobox which lists your enumeration in a user friendly way, yet allows you to have the selection work as an enum member:

How It Works

ComboBox and other element selectors in WPF allow you to display an item's property (DisplayMemberPath), while having the selection point to another property on the object (SelectedValuePath) in addition to the SelectedItem, which happens to be a KeyValuePair for a dictionary item. Setting these appropriately will allow you to create versatile lists.

Points of Interest

  • The very simple nature of this technique allows you to provide multiple dictionaries for a single enumeration, as the enum member could mean something slightly different in different parts of the UI
  • It should also play well with localization. Instead of writing the strings in the dictionary, point to your strings in the .resx file in value part the dictionary. You don't even have to change the member types in the dictionary, as the .resx data is still a string.
  • Different dictionaries can be served to the UI based on different conditions.
    • You do not need to expose all of the enumeration list, only the part you need. For example, you can have a gender.indeterminate enum member in your gender enumeration as a fallback value, but you may choose to only show the descriptions for gender.male or gender.female in your UI. This provides versatility, you don't have to redefine different enumerations or have "do not list" properties per item if the enum member does not have to be listed.

Of note, this dictionary "trick" is not confined to enumerations. For any given list of C# built-in data type, you can display a custom list of user friendly strings. The user friendly strings do not have to be in the value part, but they can be the keys in the dictionary too. You'll just need to tell in your XAML which part of the dictionary items will be displayed (the Key, or Value part), and which part of the dictionary will be selected (its Value or Key part, respectively), e.g. you can have the users select "One grand", and the selected value can be 1000 as an integer.

License

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


Written By
Web Developer
Turkey Turkey
I'm a hobbyist programmer, with considerable experience for HTML, CSS, and Javascript, and only just getting into C# out of necessity to help solve a few problems at work (late 2015)

Comments and Discussions

 
SuggestionInteresting Pin
Imagiv19-Jul-16 2:36
Imagiv19-Jul-16 2:36 
GeneralRe: Interesting Pin
hesido27-Sep-16 2:25
hesido27-Sep-16 2:25 
SuggestionClean up notations in code. Pin
Hein Pauwelyn13-Jan-16 22:23
Hein Pauwelyn13-Jan-16 22:23 

Maby it will be better that you use a big N for your enum and don't nest it with an other class and don't use a static class. Like this:

C#
public enum Nation
{
    Tr, Fr, Us, Gb, Gr
}

public class Definitions
{
    private static Dictionary<Nation, string> _nationEnumDictionary = new Dictionary<Nation, string>()
    {
        { Nation.Tr , "Turkish" },
        { Nation.Fr , "French" },
        { Nation.Us , "US citizen" },
        { Nation.Gb , "British" },
        { Nation.Gr , "Greek" }
    };

    public static Dictionary<Nation, string> NationEnumDictionary
    {
        get { return _nationEnumDictionary; } 
        set { _nationEnumDictionary = value;  }
    }
}

And in your view model you could use this:

C#
public Dictionary<Nation, string> NationalityList
{
    get { return Definitions.NationEnumDictionary; }
}

public Nation SelectedNationality { get; set;}

This notation looks more to the notation that .NET use for there notation for methodes and classes.


GeneralRe: Clean up notations in code. Pin
hesido14-Jan-16 1:18
hesido14-Jan-16 1:18 
AnswerBetter solution Pin
Clifford Nelson2-Jan-16 18:02
Clifford Nelson2-Jan-16 18:02 
GeneralRe: Better solution Pin
hesido3-Jan-16 21:11
hesido3-Jan-16 21:11 
GeneralRe: Better solution Pin
Chinatablet4-Jan-16 17:17
professionalChinatablet4-Jan-16 17:17 
GeneralRe: Better solution Pin
hesido26-Mar-16 1:04
hesido26-Mar-16 1:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.