Peregrine's View

Yet another C# / WPF / MVVM blog …

WPF General

WPF – Data Binding (Radio Buttons)

Creativity shouldn’t be following radio; it should be the other way around.
Herbie Hancock

Following on from my recent post on Data Binding within WPF / MVVM, I’ve got a couple of further cases that I recently had to deal with. This post will deal with how to handle the data-binding when allowing the user to select one item from of a defined set of options, using a group of RadioButton controls. RadioButtons can be grouped either by adding them to a common parent container, or by setting the GroupName property – only one item from the group can be selected at any one time.

The key indicator property of a RadioButton IsChecked is a (nullable) boolean value, so it makes sense to have a boolean property for each RadioButton to bind to on the ViewModel, right? Actually this can quickly lead to very verbose code if you have a lot of grouped RadioButton controls. There are also potential conflicting property update issues if you re-assign the DataContext of your UI block.

What’s the alternative then? Fortunately we already have a C# data type for selecting a specific value from a finite set – an Enum. This allows a group of related RadioButton controls to be bound to a single property. So how can we bind the boolean IsChecked property of the control to an Enum value in the ViewModel? The answer is another example of a value converter class …

public class perValueEqualsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return parameter != null && parameter.Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null && value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

… which allows any bound property to be compared against a specified value – returning true or false.

The demo project for this post shows the converter in action. Each RadioButton control in a group is bound to a single enum property, just with a different value for the converter parameter.

<Grid
    Grid.Row="2"
    Grid.Column="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="8" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="8" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <RadioButton
        Grid.Row="0"
        Content="A1"
        IsChecked="{Binding E1, Converter={StaticResource ValueEqualsConverter}, ConverterParameter={x:Static enum:DemoEnum1.A1}}" />
    <RadioButton
        Grid.Row="2"
        Content="B1"
        IsChecked="{Binding E1, Converter={StaticResource ValueEqualsConverter}, ConverterParameter={x:Static enum:DemoEnum1.B1}}" />
    <RadioButton
        Grid.Row="4"
        Content="C1"
        IsChecked="{Binding E1, Converter={StaticResource ValueEqualsConverter}, ConverterParameter={x:Static enum:DemoEnum1.C1}}" />
</Grid>

No BindingMode flag is required as ToggleButton.IsCheckedProperty is defined with FrameworkPropertyMetadataOptions.BindsTwoWayByDefault.

As usual the code samples for this blog are available on Github, along with my own personal C# / WPF library.

If you find this article useful, or you have any other feedback, please leave a comment below

Leave a Reply

Your email address will not be published. Required fields are marked *