DataGridTemplateColumn ComboBox Binding

У меня есть DataGrid, привязанный к коллекции сотрудников. Класс Employee имеет тип EmployeeCountry типа Country. Тип страны состоит из CountryId и CountryName.

У меня есть следующий XAML:

     <DataGrid ItemsSource="{Binding EmployeeList}" CanUserAddRows="True">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="CountryCombo2">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Path=DataContext.CountryList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
                                      DisplayMemberPath="CountryName" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

EmployeeList и CountryList - это свойства ObservableCollection в ViewModel, который является DataContext для окна, содержащего DataGrid. Я могу заполнить ComboBox CountryList.

Проблема: мне нужно выяснить, как установить другие свойства ComboBox, такие как SelectedValuePath, SelectedItem и т. Д., Чтобы каждая строка DataGrid правильно отображала соответствующий EmployeeCountry в ComboBox. Если свойство EmployeeCountry для Employee имеет значение NULL, то в поле со списком не должен быть выбран элемент.

Обновление: я также не могу добавить новую строку в DataGrid, хотя для свойства CanUserAddRows установлено значение true.

2 ответа

Мне удалось решить мою проблему, используя вопрос, упомянутый в одном из моих комментариев. Просто разместил XAML, который помог заставить его работать:

 <DataGrid ItemsSource="{Binding EmployeeList}" CanUserAddRows="True" AutoGenerateColumns="False" Margin="0,0,0,90">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="CountryCombo2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Path=DataContext.CountryList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
                                      DisplayMemberPath="CountryName" 
                                      SelectedItem="{Binding EmployeeCountry, Mode=TwoWay}"
                                      SelectedValue="{Binding EmployeeCountry.CountryId}"
                                      SelectedValuePath="CountryId" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

Я бы сделал что-то подобное

 <ComboBox SelectedValuePath="CountryName" SelectedItem="{Binding Country}"  ItemsSource="{Binding Path=DataContext.CountryList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}">

И просто чтобы показать вам, что я дал вам работы, я помещаю полный написанный код.

public class Employees :INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    private string _name;
    public string Name
    {
        get
        {
            return _name; 
        }

        set
        {
            if (_name == value)
                return;
            _name = value;
            OnPropertyChanged();
        }
    }

    private Country _employeeCountry;
    public Country EmployeeCountry
    {
        get
        {
            return _employeeCountry;
        }

        set
        {
            if (_employeeCountry == value)
                return;
            _employeeCountry = value;
            OnPropertyChanged();
        }
    }
}

public class Country
{
    private string _name;
    public string Name
    {
        get
        {
            return _name;
        }

        set
        {
            if (_name == value)
                return;
            _name = value;
        }
    }
}

private static ObservableCollection<Country> _countryList = new ObservableCollection<Country>(new []{ new Country{Name="US"}, new Country{Name="UK"}});

public ObservableCollection<Country> CountryList
{
    get
    {
        return _countryList;
    }
}

private ObservableCollection<Employees> _employeeList = new ObservableCollection<Employees>(new[] { new Employees { Name = "Ty", EmployeeCountry = _countryList.First() }, new Employees { Name = "Dude" } });

public ObservableCollection<Employees> EmployeeList
{
    get
    {
        return _employeeList;
    }
}

И Xaml

<DataGrid ItemsSource="{Binding EmployeeList}" CanUserAddRows="True">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="CountryCombo2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Path=CountryList, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" DisplayMemberPath="Name"
                                 SelectedValuePath="Name" SelectedItem="{Binding EmployeeCountry}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
Другие вопросы по тегам