I recently began implemented binding two radio buttons to a single enumeration value on an object, and was faced with two problems:
1) How do I bind the IsChecked boolean to an enumeration?
2) Once 1) was completed and even though it was using TwoWay binding, when the enum value was set outside of the UI, then the radio button would loose it's binding.
Here are the solutions:
1) Use a ValueConverter combined with ConverterParameter to bind the enumeration to the boolean IsChecked:
XAML:
<EnumBooleanConverter x:Key="ebc" /> <!-- declared in the UserControl Resources -->
...
<RadioButton x:Name="rdoMale" Content="Male" IsChecked="{Binding Path=Gender, Mode=TwoWay, Converter={StaticResource ebc}, ConverterParameter=Male}"/>
<RadioButton x:Name="rdoFemale" Content="Female" Margin="5" IsChecked="{Binding Path=Gender,Mode=TwoWay, Converter={StaticResource ebc},ConverterParameter=Female}"/>
C#:
public class EnumBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var ParameterString = parameter as string;
if (ParameterString == null)
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object paramvalue = Enum.Parse(value.GetType(), ParameterString);
return paramvalue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var ParameterString = parameter as string;
if (ParameterString == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, ParameterString);
}
#endregion
}
..that worked great, until I set the value of the enum from code (ie: not by clicking the radio buton), so...
2) turns out, having read this post, it seems that if radio buttons belong to the same group, they confuse each other (or at least that's how I interpreted it). So I changed the XAML to:
<RadioButton GroupName="Male" x:Name="rdoMale" Content="Male" IsChecked="{Binding Path=Gender, Mode=TwoWay, Converter={StaticResource ebc}, ConverterParameter=Male}"/>
<RadioButton GroupName="Female" x:Name="rdoFemale" Content="Female" IsChecked="{Binding Path=Gender,Mode=TwoWay, Converter={StaticResource ebc},ConverterParameter=Female}"/>
... and it's "all sorted m8!" :)
10 comments:
Thanks jax, I was struggling with same thing for past few hours, your post saved me.
Thank you, this helped immensely.
Worked perfectly the first time.
This was great help...thank you very much, sir :)
Strange enough, changing the GroupName didn't work for me. I had three RadioButtons and always the RadioButton tied to the first element in the enum would "stick" to true while the other two RadioButtons worked as expected.
My solution: assigning a starting value of 1 to my first element in the enum.
Try this as an experiment in your code:
- Remove the GroupNames from your buttons.
- Change your enum to the following:
enum Genders
{
Male = 1,
Female
}
Works beautifully for me although I am unsure exactly why. I am assuming that the converter doesn't like emum values that are assigned 0.
(WPF .NET 3.5 C#)
BTW why don't you just write:
return paramvalue.Equals(value)
instead of:
if (paramvalue.Equals(value))
return true;
else
return false;
Humanier - updated post.
Thanks, this post was very useful for me!
doesn't it strike you as odd that you can't use the same radio group for what is logically one group of radiobuttons?
Things "freak out" if you use one group because your ConvertBack() is flawed.
Shawn - feel free to offer a correct solution where things don't freak out.
Post a Comment