Clara's Notes on Technology
Notes to me and the world

WPF RadioButtons and data binding

Friday, October 17, 2008 8:46 AM

There is a well-known issue with WPF RadioButton controls with data binding: when a radio button is unchecked the data binding is not undone. For example, suppose you have the following two radio buttons in the same group linked to a the "IsSuccess" (of type bool?) attribute of an object:

<RadioButton Grid.Row="0" Grid.Column="0" GroupName="rbGroup" Margin="8,0,0,0" VerticalAlignment="Center" Content="Success" x:Name="rbSuccess" IsChecked="{Binding Path=IsSuccess, Mode=TwoWay, Converter={StaticResource nullableBooleanConverter}}" /> <RadioButton Grid.Row="0" Grid.Column="1" GroupName="rbGroup" Margin="8,0,0,0" VerticalAlignment="Center" Content="Failure" x:Name="rbFailure" />

When you check the rbSuccess radio button, the IsSuccess field becomes "true", but when you check on the rbFailure radio button (and thus uncheck the rbSuccess one), the IsSuccess field is still true!

The problem is discussed here. There are several solutions. This blog explains one (using a control template). Another popular one is to use a ListBox restyled as a radio button. However, this causes other problems such as being unable to scroll past the radiobuttons (they are really a listbox, so scrolling is done inside the list).

The solution I have found is to put each radio button in a different group and link their checked/unchecked values via the converter. Like this:

<RadioButton Grid.Row="1" Grid.Column="0" GroupName="rbGroupSuccess" Margin="8,0,0,0" VerticalAlignment="Center" Content="Success" x:Name="rbSuccess" IsChecked="{Binding Path=IsSuccess, Mode=TwoWay, Converter={StaticResource nullableBooleanConverter}, ConverterParameter=true}" /> <RadioButton Grid.Row="1" Grid.Column="1" GroupName="rbGroupFailure" Margin="8,0,0,0" VerticalAlignment="Center" Content="Failure" x:Name="rbFailure" IsChecked="{Binding Path=IsSuccess, Mode=TwoWay, Converter={StaticResource nullableBooleanConverter}, ConverterParameter=false}" />

And here is the converter:

[ValueConversion(typeof(bool?), typeof(bool))] public class SuccessConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool param = bool.Parse(parameter.ToString()); if (value == null) { return false; } else { return !((bool)value ^ param); } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { bool param = bool.Parse(parameter.ToString()); return !((bool)value ^ param); } }

Notice the converter parameter. Its role is to make sure that I get opposite values for the two radio buttons (when one is true, the other is false).

value
(IsSuccess)
param

result
RadioButton.IsChecked = !(value ^ param)

true true true
false true false
true false false
false false true

(^ is the XOR operator in C#)

Technorati Tags: ,

 


Feedback

# re: WPF RadioButtons and data binding

I'm sorry but I am definitely a newbie...What do you mean by "linked to a the "IsSuccess" attribute of an object"? 12/18/2008 10:29 PM | Al

# re: WPF RadioButtons and data binding

Thx a lot. This really saved my day! 4/17/2009 11:31 AM | Frederico Teles

# re: WPF RadioButtons and data binding

Hi. Thanks for the very straightforward tutorial.
I'm trying to use RadioButtons and binding them to a boolean property in the DataContext.
This is a TwoWay binding.
The RadioButton DOES display the present state of the DataContext Property.. but ANY changes to the button state on the UI do NOT trigger the Property Setter. This having been checked within the object value and by putting a breakpoint in the Setter of the property.
Would you have a clue as to what I may be doing wrong?

Thanks! 5/22/2009 12:24 AM | Arvind

# re: WPF RadioButtons and data binding

Your solution does not work. It shows some compilation errors. 6/2/2009 11:45 AM | Fayaz

# re: WPF RadioButtons and data binding

Thanks,

It really worked, However why should the group name be different?

7/13/2009 5:13 AM | Raul Dsouza

# re: WPF RadioButtons and data binding

So... what do you do if you have 3 or more radio buttons? 7/15/2009 9:54 AM | William Garrison

# re: WPF RadioButtons and data binding

Thanks Clara,

Works excellent. 8/14/2009 3:35 AM | Frank

# re: WPF RadioButtons and data binding

I generally make an 'EqualityValueConverter' which does the same sort of thing but is generic for any type (and therefore can be used in other scenarios aswell) 8/18/2009 2:22 AM | MF

# re: WPF RadioButtons and data binding

Wasn't working for me until I realized I hadn't set different group names. Now it works great thanks! 9/10/2009 12:37 PM | jj

# re: WPF RadioButtons and data binding

I must be really stupid at this programming thing, but isn't this:

!((bool)value ^ param)

Equal to this:

(bool)value == param

This ensures that the values are equivalent and it's a billion times easier to read! 9/18/2009 9:35 PM | Nick

# re: WPF RadioButtons and data binding

A not so elegant but failsafe and much simpler solution is to connect the Checked Event to the ViewModel by hand as so:

private void All_Checked(object sender, System.Windows.RoutedEventArgs e)
{
if (ViewModel != null)
{
ViewModel.ShowAll = true;
}
}

private void SelectedOnly_Checked(object sender, System.Windows.RoutedEventArgs e)
{
if (ViewModel != null)
{
ViewModel.ShowSelectedOnly = true;
}
}

This will do until WPF matures enough to not contain obvious bugs like these.
At that point I can remove the EventHandler and bind directly without changing much of my code. 10/18/2009 10:46 AM | Thorsten

# re: WPF RadioButtons and data binding

What if you're binding to an enum and there are more than two radio buttons? What would the converter look like then? 10/22/2009 11:08 AM | Brian

# re: WPF RadioButtons and data binding

It works. Thank you! 12/3/2009 3:11 PM | Sam

# re: WPF RadioButtons and data binding

Hi, the solution doesn't work for me, it keeps both RadioButtons checked. 3/2/2010 5:38 PM | Carlo Toribio

# re: WPF RadioButtons and data binding

nvm, it suddenly worked, not sure why. Thanks 3/2/2010 5:43 PM | Carlo Toribio

Post a comment