1

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;
    }
Marij Khan
  • 151
  • 1
  • 12

1 Answers1

2

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>
mm8
  • 163,881
  • 10
  • 57
  • 88
  • The original answer threw an exception since the value was not an int but a string, "male" or "female". I tried `Enum.TryParse(value, out Gender myStatus);` and it worked so thank you for pointing me in the right direction. Do I have to change the convertback method to return the string of the enum as well? – Marij Khan Jul 18 '19 at 10:34
  • @MarijKhan: If the type of the column in the `DataTable` is a string, you need to cast from `string` instead of `int´ but you don't need to implement `ConvertBack` as it's never called for a `OneWay` binding. – mm8 Jul 18 '19 at 11:34