Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data binding Int property to Enum in WPF

Below is a simplified example of a class I have:

public class ExampleClassDto 
{
     public int DriverTypeId
}

I also have an Enum that maps the Ids of DriverType to meaningful names:

public enum DriverType
{
    None,
    Driver1,
    Driver2,
    Driver3
}

But I want to bind this in XAML to a combobox. Unfortunately, because of the type mismatch, it doesn't like this. So in my ViewModel, I have to create a second property to map the two

public class ExampleViewModel
{
    private ExampleClassDto _selectedExampleClass;
    public ExampleClassDto SelectedExampleClass
    {
        get { return _selectedExampleClass; }
        set
        {
            _selectedExampleClass = value;
            SelectedDriverType = (DriverType)_selectedExampleClass.DriverTypeId;
            OnPropertyChanged("SelectedDeviceType");
        }
    }

public DriverType SelectedDriverType
{
    get
        {
            if (_selectedDeviceType != null) 
            { 
                return (DriverType)_selectedDeviceType.DriverTypeId;
            }
            return DriverType.None;
        }
        set
        {
            _selectedDeviceType.DriverTypeId = (int) value;
            OnPropertyChanged("SelectedDriverType");
        }
}
}

Then I bind to the new property.

<ComboBox ItemsSource="{Binding Source={StaticResource DriverTypeEnum}}" SelectedValue="{Binding SelectedDriverType, Mode=TwoWay}"/>

Now, this WORKS, but feels very gross. It's using SelectedDriverType as a converter. I want to avoid having to make the DTO's property a different type. Are there other, more elegant, solutions?

Thanks!

like image 270
Killnine Avatar asked Dec 20 '13 15:12

Killnine


1 Answers

You can have a generic converter say EnumConverter which will convert int to Enum to show it on XAML and convert back from Enum to int to set back in your ViewModel class.

It will work for any enum type. You just need to pass on type of enum in converter parameter.

public class EnumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                          System.Globalization.CultureInfo culture)
    {
        Enum enumValue = default(Enum);
        if (parameter is Type)
        {
            enumValue = (Enum)Enum.Parse((Type)parameter, value.ToString());
        }
        return enumValue;
     }

     public object ConvertBack(object value, Type targetType, object parameter, 
                               System.Globalization.CultureInfo culture)
     {
         int returnValue = 0;
         if (parameter is Type)
         {
             returnValue = (int)Enum.Parse((Type)parameter, value.ToString());
         }
         return returnValue;
     }
}

XAML usage :

<ComboBox ItemsSource="{Binding Source={StaticResource DriverTypeEnum}}"
          SelectedValue="{Binding DriverTypeId,
                                Converter={StaticResource EnumConverter}, 
                                ConverterParameter={x:Type local:DriverType}}"/>

local is namespace where your DriverType is declared.

like image 65
Rohit Vats Avatar answered Sep 22 '22 13:09

Rohit Vats