Search code examples
c#.netwpfmvvm-lightwpfdatagrid

enum DataGridComboBoxColumn empty when AutoGenerateColumns = false in WPF/MVVMLight


Developing a WPF app using MVVLight.

In my models, I have:

..an enum named AttributeType:

public enum AttributeType
    {
        TypeA = 0,
        TypeB = 1,
    }

..an Attribute class which exposes a Type property of type AttributeType:

public class Attribute : ObservableObject
{       
    //constructors, other fields etc omitted for brevity

    private AttributeType type;
    public AttributeType Type
    {
        get { return type; }
        set 
        { 
            type = value;
            RaisePropertyChanged(() => Type);
        }
}

..and a DataSet class with an Attributes property of type List<Attribute>:

public class DataSet : ObservableObject
{       
    //constructors, other fields etc omitted for brevity

    private ObservableCollection<Attribute> attributes;
    public ObservableCollection<Attribute> Attributes
    {
        get { return attributes; }
        set 
        { 
            attributes = value;
            RaisePropertyChanged(() => Attributes);
        }
    }
}   

In my main window, I have a DataGrid which is bound to DataSet.Attributes and has AutoGenerateColumns="true", as such:

<DataGrid Grid.Row="2" Grid.Column="0" Margin="5" CanUserAddRows="false" AutoGenerateColumns="true" ItemsSource="{Binding DataSet.Attributes}">

Whenever I instantiate the DataSet class via my ViewModel and populate DataSet.Attributes the DataGrid correctly displays a DataGridComboBoxColumn for Attribute.Type with all the possible AttributeType enum values.

If, however, I turn AutoGenerateColumns="false" to set my own columns:

<DataGrid Grid.Row="2" Grid.Column="0" Margin="5" CanUserAddRows="false" AutoGenerateColumns="false" ItemsSource="{Binding DataSet.Attributes}">
     <DataGrid.Columns>
          <DataGridTextColumn Header="name" Width="*" Binding="{Binding Name}" />
          <DataGridComboBoxColumn Header="type" Width="*" SelectedItemBinding="{Binding Type}" />
     </DataGrid.Columns>
</DataGrid>

..the DataGridComboBoxColumn this time shows nothing. Other columns and their corresponding bindings work fine. What am I missing here?


Solution

  • Please use the following steps. It works fine (tested).

    1. Add resource to your data grid (or at a higher level).

            <DataGrid.Resources>
                <!--Create list of enumeration values-->
                <ObjectDataProvider x:Key="myEnum" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
                    <ObjectDataProvider.MethodParameters>
                        <x:Type Type="local:AttributeType"/>
                    </ObjectDataProvider.MethodParameters>
                </ObjectDataProvider>
            </DataGrid.Resources>
    

    2. Update the binding of DataGridComboBoxColumn. The static resource is required to resolve the members of enumeration. See the MethodName in step 1 which returns the values of the bound object type.

            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Value" ItemsSource="{Binding Source={StaticResource myEnum}}" Width="100"
                SelectedValueBinding="{Binding Type}" />
            </DataGrid.Columns>
    

    Update 1

    You will also need to define a local namespace at the Main container level. Replace WpfApplication1 with your namespace path.

      xmlns:System="clr-namespace:System;assembly=mscorlib" 
    xmlns:local="clr-namespace:WpfApplication1"