Search code examples
c#wpfdata-bindingwpfdatagriddatagridcomboboxcolumn

WPF DataGridComboBoxColumn dynamic binding of Enum


I have a datagrid to which I set item source List<User>. One of the properties of User is Department which is Enum with descriptions.

In the datagrid Departments are displayed as combobox for a user to select one. I need to bind enum value and description to the DataGridComboBoxColumn.

So far I managed either to bind Enum to DataGridComboBoxColumn.ItemsSource thus it works but the description isn't taken into account. Or set collection of Value, Description to DataGridComboBoxColumn.ItemsSource and set DisplayMemberPath, SelectedValuePath. But in this case the value doesn't bind to DataGridComboBoxColumn.

The View:

 <DataGrid x:Name="userData" HorizontalAlignment="Stretch" Margin="10,157,10,80" VerticalAlignment="Stretch" Height="Auto" Width="Auto"
 AutoGeneratingColumn="UserData_OnAutoGeneratingColumn" DisplayMemberPath="Description"/>

The Code:

    private void UserData_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.Column.SortMemberPath == "Department")
        {
            (e.Column as DataGridComboBoxColumn).ItemsSource = EnumExtension.ProvideValue();

            (e.Column as DataGridComboBoxColumn).DisplayMemberPath = "Description";
            (e.Column as DataGridComboBoxColumn).SelectedValueBinding = new Binding("Value");
            (e.Column as DataGridComboBoxColumn).SelectedValuePath = "Value";
        }
    }

Enum extension:

public static class EnumExtension
{
    public static List<ValueDescriptionVm<Departments>> ProvideValue()
    {
        return Enum.GetValues(typeof(Departments))
        .Cast<object>()
        .Select(enumValue => new ValueDescriptionVm<Departments>()
        {
            Value = (Departments)enumValue,
            Description = GetDescription((Enum)enumValue)
        }).ToList();
    }

    private static string GetDescription(Enum enumValue)
    {
        FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
        var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attributes.Length > 0)
        {
            return attributes[0].Description;
        }

        return enumValue.ToString();
    }
}

Solution

  • The path of the SelectedValueBinding should be the name of the property of the User class:

    (e.Column as DataGridComboBoxColumn).SelectedValueBinding = new Binding("Department");
    

    Then the binding should work provided that the type of the Department property of the User class and the Value property of the ValueDescriptionVm<Departments> class is the same.