Click here to Skip to main content
Click here to Skip to main content

Tagged as

Generic ValueConverter for Binding Enumerations to Check Boxes

, 15 Oct 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Generic ValueConverter for Binding Enumerations to Check Boxes

Summary

There are many times that there are a group of radio buttons on a form that are associated with a single enumeration. What many developers will do is create a separate property in the ViewModel for each radio button. I do not like this. First I think that this is too much of a dependency between the View and the ViewModel. It also adds a whole bunch of properties to the ViewModel that just makes the ViewModel bigger, and it requires excess code for each property to convert it to and from an enumeration. All that is really needed is a single property for each enumeration, and a generic ValueConverter.

Background

After so many times of having to deal with radio buttons and ViewModels, I finally decided to create a generic way of dealing with them.

Implementation

To bind an enumeration to the IsChecked property of a group of radio buttons, a ValueConverter will be required; there is just no way to bind an enumeration to a bool without converting it. It is possible to create a separate ValueConverter class for each radio button, but that is not required since the ValueConverter methods have a parameter argument which is set in the XAML by using the ConverterParameter argument of the Binding. The idea is that each radio button IsChecked argument is bound to the Enumeration property using the EnumValueConverter with a ConverterParameter equal to a string which is the name of the specific enumeration.

class EnumValueConverter : IValueConverter
{
	public object Convert(object value, Type targetType, 
		object parameter, System.Globalization.CultureInfo culture)
	{
		if (value == null || parameter == null)
			return false;
		return value.ToString() == parameter.ToString();
	}

	public object ConvertBack(object value, Type targetType, 
		object parameter, System.Globalization.CultureInfo culture)
	{
		if (value == null || parameter == null)
			return null;
		var rtnValue = parameter.ToString();
		try
		{
			object returnEnum = Enum.Parse(targetType, rtnValue);
			return returnEnum;
		}
		catch
		{
			return null;
		}
	} 
}

In the example code, I have added three debug methods to aid in finding errors, but have removed these methods for clarity. As can be seen, the code is fairly straight forward. In the Convert method, the ToString() method is used to convert the enumeration from the ViewModel to a string which is then compared to the ConverterParmeter; if equal, a the value returned is true. In the ConvertBack method, the Enum.Parse method is used to convert the ConverterParmeter from the control into the appropriate enumeration for the ViewModel if the value argument in. This fortunately works because in the case of radio buttons, they only need to deal with being changed to the checked state, so never have to deal with changes to the unchecked state; that is automatic. If the Parse does not work, a null is returned (which is also the case for null value and parameter argument, which has no effect since null is invalid for an enumeration (Binding does not allow changes for invalid values).

Wiring up the XAML to the property and converter is quite straightforward. In the example, there is a very simple enum:

public enum TestEnum
{
	A, B, C
}

The property in the ViewModel for this enumeration is also very straightforward:

public TestEnum EnumBinding
{
	get
	{
		return _enumBinding;
	}
	set
	{
		if (_enumBinding != value)
		{
			_enumBinding = value;
			if (PropertyChanged != null)
				PropertyChanged(this, new 
				PropertyChangedEventArgs("EnumBinding"));
		}
	}
}

Now all that is needed is the XAML, which includes the resource definition for the converter and the checkboxes with the binding definition using the converter and the ConverterParameter:

<Window x:Class="GenericEnumValueConverter.MainWindow"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:local="clr-namespace:GenericEnumValueConverter"
		Title="Enumerator Value Converter Example" 
		Height="200" Width="250">
	<Window.Resources>
		<local:EnumValueConverter x:Key="EnumValueConverter"/>
	</Window.Resources>
	<StackPanel HorizontalAlignment="Center" 
		    VerticalAlignment="Center">
		<RadioButton Content="A" 
			IsChecked="{Binding EnumBinding,
				Converter={StaticResource EnumValueConverter},
				ConverterParameter=A}"/>
		<RadioButton Content="B" 
			IsChecked="{Binding EnumBinding,
				Converter={StaticResource EnumValueConverter},
				ConverterParameter=B}"/>
		<RadioButton Content="C" 
			IsChecked="{Binding EnumBinding,
				Converter={StaticResource EnumValueConverter},
				ConverterParameter=C}"/>
	</StackPanel>
</Window>

The actual example includes a textbox to confirm that the property for the enumeration is actually the value of the radio buttons, and an extra radio button containing a bad value to show what happens when there is a bad enumeration value in the XAML (during debug, pressing the “Bad Value” radio button creates a message in the Output window).

Conclusion

This is a very clean way to connect an enumeration to radio buttons. The same converter can also be used for other purposes with a little bit of extra code, such as setting the visibility of controls based on a state that is specified by an enumeration (need to covert the bool value to a Visibility enumeration). It removes a lot of complexity from the ViewModel, and uses a single converter for all instances where enumerations are bound to check boxes (or other controls). In all, it is a very clean way to reduce code, and improve maintainability.

History

  • 15th October, 2011: Initial version

License

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

Share

About the Author

Clifford Nelson
Software Developer (Senior) ETeam/Delloitte
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last three years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with NBC Universal in Universal City, CA

Comments and Discussions

 
GeneralMy vote of 1 PinmemberWouter Huysentruit3-Nov-12 2:52 
GeneralRe: My vote of 1 PinmemberClifford Nelson3-Nov-12 7:53 
GeneralRe: My vote of 1 PinmemberWouter Huysentruit3-Nov-12 8:01 
QuestionThoughts PinmemberPIEBALDconsult15-Oct-11 6:13 
AnswerRe: Thoughts PinmemberClifford Nelson15-Oct-11 6:47 
AnswerRe: Thoughts PinmvpSacha Barber16-Oct-11 22:51 
GeneralRe: Thoughts PinmemberPIEBALDconsult17-Oct-11 3:53 
GeneralRe: Thoughts PinmemberJürgen Röhr24-Oct-11 4:14 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150327.1 | Last Updated 15 Oct 2011
Article Copyright 2011 by Clifford Nelson
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid