Привязка WPF SelectedItemBinding DataGridComboBoxColumn

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

 public class Student
    {
        public string Department { get; set; }

    public string Level { get; set; }

    public Gender Gender { get; set; }

    public string Nationality { get; set; }

}

У меня есть еще один класс, содержащий список стран в объявленной коллекции, как показано ниже.

public class Countries
    {
 public static ObservableCollection<string> Nationalities { get; } = new ObservableCollection<string>()
        {
            "Afghanistan",
            "Albania",
            "Algeria",
            "Andorra",
            "Angola",
            "Anguilla",
            "Antigua & Barbuda",
            "Argentina",
            "Armenia",
            "Australia",
            "Austria",
            "Azerbaijan",
            "Bahamas",
            "Bahrain",
            "Bangladesh",
            "Barbados",
            "Belarus",
            "Belgium",
            "Belize",
            "Benin",
            "Bermuda",
            "Bhutan",
            "Bolivia",
            "Bosnia & Herzegovina",
            "Botswana",
            "Brazil",
}

В моей модели представления я объявил наблюдаемую коллекцию, которая инициализируется списком стран. Это делается внутри конструктора моделей представлений, как показано ниже.

public class ViewModel : BaseViewModel
    {
     public ObservableCollection<string> Nationalities { get; private set; }
         public ViewModel()
        {

            // Set the nationality list
            Nationalities = Countries.Nationalities;

        }
}

Теперь я создал свой DataGridComboBoxColumn так,

 <DataGrid.Columns>
                        <DataGridComboBoxColumn Width="Auto"
                                                    SelectedItemBinding="{Binding Path=Student.Nationality}"
                                                    Header="Nationality" 
                                                    x:Name="NationalityComboBox2">
                            <DataGridComboBoxColumn.EditingElementStyle>
                                <Style TargetType="ComboBox">
                                    <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Nationalities, ElementName=StudentListGrid}" />
                                </Style>
                            </DataGridComboBoxColumn.EditingElementStyle>
                        </DataGridComboBoxColumn>
                    </DataGrid.Columns>

Когда я запускаю свое приложение, в DataGridComboBoxColumn есть все страны, но когда я выбираю конкретную страну, она не отображается. Я видел подобные вопросы в Интернете, но я не видел ответа, который работал бы в моем случае. Какие-либо предложения?


person Ken Janka    schedule 13.06.2018    source источник


Ответы (3)


Вместо использования DataGridComboBoxColumn вы можете использовать DataGridTemplateColumn для достижения того же самого. Возможно, вам придется написать код для сохранения стиля текстового поля и поля со списком.

 <DataGridTemplateColumn  Header="Nationality" >
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Nationality}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedItem="{Binding Nationality}" ItemsSource="{Binding Path=DataContext.Nationalities, ElementName=StudentListGrid}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
person CodeMoon    schedule 13.06.2018

Я думаю, вам нужно реализовать интерфейс INotifyPropertyChanged на Student

public class Student : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

    public string Department { get; set; }

    public string Level { get; set; }

    public Gender Gender { get; set; }

    private string _nationality;
    public string Nationality 
    { 
        get
        {
            return _nationality;
        }  
        set
        {
            if(value != _nationality)
            {
                _nationality = value;
                OnPropertyChanged(nameof(Nationality));
            }
         } 
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
person eye_am_groot    schedule 13.06.2018
comment
Спасибо. Я реализовал это в классе BaseViewModel. Проблема с ComboBoxColumn заключается в том, что он вообще не отображает выбранное значение. Я думал, что это как-то связано со свойством SelectedItemBinding DAtaGridComboBoxColumn. - person Ken Janka; 13.06.2018

Предполагая, что ItemsSource из DataGrid является IEnumerable<Student>, вы должны привязаться к Nationality вместо Student.Nationality:

<DataGridComboBoxColumn Width="Auto"
                        SelectedItemBinding="{Binding Nationality}"
                        Header="Nationality" 
                        x:Name="NationalityComboBox2">
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Nationalities, ElementName=StudentListGrid}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
person mm8    schedule 13.06.2018
comment
@KenJanka: Ты не пробовал? Или вы не смогли переименовать путь привязки? - person mm8; 14.06.2018