Search code examples
c#wpfdatagriddatagridcomboboxcolumn

DataGridComboBoxColumn initial value not displaying


I have a DataGridComboBoxColumn that's bound to an enum. The dropdown displays the values of enum correctly, but the combobox does not display any value initially. I am trying to bind the selected value to a Gender property of a DataTable that's the source of my DataGrid. I have tried the methods in similar questions like SelectedItemBinding="{Binding Gender}" or SelectedValueBinding="{Binding Gender}" but they don't work for me.

I have also tried to put a combobox inside a DataGridTemplateColumn but it does not display the Gender value initially I have tried SelectedValue="{Binding Gender}" and SelectedValuePath="{Binding Gender}" but to no avail. SelectedIndex = "0" works, but it's of no use to me since I want the initial value to come from a property.

The binding works when I bind the property to a DataGridTextColumn as it displays the correct value i.e male/female.

XAML:

<ObjectDataProvider x:Key="genderEnum" xmlns:sys="clr-namespace:System;assembly=mscorlib" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="enumLoc:Gender"/>
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Grid DataContext="ViewMembers.xaml.cs">
    <DataGrid x:Name="memberDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding Path=memberTable, Mode=TwoWay}" RowDetailsVisibilityMode="VisibleWhenSelected" Width="1200" Height="600" GridLinesVisibility="None" >
        <DataGrid.Columns>                
            <DataGridComboBoxColumn x:Name="memberGenderColumn" SelectedItemBinding="{Binding Gender}" ItemsSource="{Binding Source={StaticResource genderEnum}}"  Header="Gender" Width="60">
            <DataGridTemplateColumn Header="Gender">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Source={StaticResource genderEnum}}" SelectedValue="{Binding Gender}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

XAML.cs:

    DataTable memberTable = new DataTable();
    MemberDatabase members = MemberDatabase.GetApplicationDatabase();

    public ViewMembers()
    {
        InitializeComponent();
        memberTable = members.GetAllMembers();
        memberTable.AsEnumerable().ToList().ForEach(row =>
        {
            var cellList = row.ItemArray.ToList();
            row.ItemArray = cellList.Select(x => x.ToString().Trim()).ToArray();
        });
        this.DataContext = memberTable;
        memberDataGrid.ItemsSource = memberTable.DefaultView;
    }

Solution

  • You can make this work by creating a very simple converter class that casts from int to your enum:

    public class EnumConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (Gender)value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
    }
    

    XAML:

    <DataGrid x:Name="memberDataGrid" ...>
        <DataGrid.Resources>
            <local:EnumConverter x:Key="EnumConverter" />
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridComboBoxColumn x:Name="memberGenderColumn" 
                                    SelectedItemBinding="{Binding Gender, Converter={StaticResource EnumConverter}}" 
                                    ItemsSource="{Binding Source={StaticResource genderEnum}}" Header="Gender" Width="60">
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>