Using enum descriptions to string/text binding In my WP8 application I need to show a couple of radio buttons to let the user select a value out of an enum. I don't want to hardcode either the value or the text (description) showed to the user. I would like my Model/ViewModel drive them for me.

As of now, this is what I have:

//enum defined in model
 public enum Units
    {
        [Description ("Meters/km")]
        Metric,
        [Description ("Feet/Miles")]
        Imperial
    }


Converters defined to handle string and Boolean conversions

//&lt;Summary&gt;Converts ENum to boolean and back
// Convert: uses parameter passed in, returns true if current value of the Enum matches parameter
//ConvertBack: if value is true, sets the value of the ENum to parameter passed in
//&lt;/summary&gt;
[ValueConversion (typeof (Enum), typeof (Boolean))]
public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if ( parameterString == null )
            return DependencyProperty.UnsetValue;

        if ( Enum.IsDefined (value.GetType (), value) == false )
            return DependencyProperty.UnsetValue;

        object parameterValue = Enum.Parse (value.GetType (), parameterString);

        return parameterValue.Equals (value);

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals (true) ? Enum.Parse(targetType, parameter as String) : DependencyProperty.UnsetValue;
    }
}

//&lt;Summary&gt;Converts ENum to strings, uses Description for the parameter passed in, or parameter as string&lt;/summary&gt;
[ValueConversion (typeof (Enum), typeof (String))]
public class EnumToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if ( parameterString == null )
            return DependencyProperty.UnsetValue;

        if ( Enum.IsDefined (value.GetType (), value) == false )
            return DependencyProperty.UnsetValue;

        var desc = (value.GetType ().GetField (parameterString).GetCustomAttributes (typeof (DescriptionAttribute), false).FirstOrDefault() as DescriptionAttribute);
        if ( desc != null )
            return desc.Description;
        else
            return parameter.ToString ();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException ();
    }
}


In the XAML:



   &lt;Grid  Margin="0,10,0,0"&gt;
    &lt;Grid.RowDefinitions&gt;
        &lt;RowDefinition /&gt;
        &lt;RowDefinition /&gt;
    &lt;/Grid.RowDefinitions&gt;
    &lt;Grid.ColumnDefinitions&gt;
        &lt;ColumnDefinition Width="Auto" /&gt;
        &lt;ColumnDefinition Width="Auto" /&gt;
    &lt;/Grid.ColumnDefinitions&gt;
    &lt;TextBlock Text="How do you measure distance?"
               Margin="6,0,0,0"
               Grid.ColumnSpan="2"
               Grid.Row="0" /&gt;
    &lt;RadioButton Grid.Row="1"
                 Grid.Column="0"
                 Content="{Binding PreferredUnit, ConverterParameter=Metric, Converter={StaticResource EnumToStringConverter}}"
                 IsChecked="{Binding PreferredUnit, ConverterParameter=Metric, Converter={StaticResource EnumToBooleanConverter}, Mode=TwoWay}" /&gt;
    &lt;RadioButton Grid.Row="1"
                 Grid.Column="1"
                 Content="{Binding PreferredUnit, ConverterParameter=Imperial, Converter={StaticResource EnumToStringConverter}}"
                 IsChecked="{Binding PreferredUnit, ConverterParameter=Imperial, Converter={StaticResource EnumToBooleanConverter}, Mode=TwoWay}" /&gt;
&lt;/Grid&gt;


Does anyone here think I am on the right track with my approach? Any suggestions on improving the code (in terms of logic, clarity, performance)?
This looks perfectly reasonable.  In fact, the only thing I would really change is this:



string parameterString = parameter as string;
if ( parameterString == null )
    return DependencyProperty.UnsetValue;

if ( Enum.IsDefined (value.GetType (), value) == false )
    return DependencyProperty.UnsetValue;


You have this in both Convert methods, and it would be just as clear like this:

string parameterString = parameter as string;
if ( parameterString == null || !Enum.IsDefined (value.GetType (), value) )
    return DependencyProperty.UnsetValue;


Additionally, you could concatenate this:

object parameterValue = Enum.Parse (value.GetType (), parameterString);
return parameterValue.Equals (value);


Like this:

return Enum.Parse (value.GetType(), parameterString).Equals (value);


For your XAML, you do not need to put each property on its own individual line.  I typically only break them up when they do not fit on my screen all at once, more like this

&lt;TextBlock Text="How do you measure distance?" Margin="6,0,0,0" Grid.ColumnSpan="2" Grid.Row="0" /&gt;
&lt;RadioButton Grid.Row="1" Grid.Column="0"
             Content="{Binding PreferredUnit, ConverterParameter=Metric, Converter={StaticResource EnumToStringConverter}}"
             IsChecked="{Binding PreferredUnit, ConverterParameter=Metric, Converter={StaticResource EnumToBooleanConverter}, Mode=TwoWay}" /&gt;


Finally, for your UI, you most likely want to label your radio buttons as what they are, and perhaps change your UI a little to accommodate the labels and still look good.  I would recommend a ComboBox if you have trouble adjusting the UI to look good.  You could then bind the SelectedItem or SelectedIndex to a value in your VM and use a converter to change the value as needed.

&lt;ComboBox Text="Label"&gt;
    &lt;ComboBoxItem&gt;Metric (meters)&lt;/ComboBoxItem&gt;
    &lt;ComboBoxItem&gt;Imperial (feet)&lt;/ComboBoxItem&gt;
&lt;/ComboBox&gt;