Wednesday, February 18, 2009

WPF Radio button binding (Enums and bug fixes)

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!" :)