Как привязать данные к DataGridComboBoxColumn в DataGrid с помощью MVVM

Это сводит меня с ума. У меня есть DataGrid, у которого есть DataGridComboBoxColumn, который я хочу, чтобы пользователь мог использовать для выбора. Это основная схема моей сетки.

<DataGrid ItemsSource="{Binding GoalList}" DockPanel.Dock="Bottom" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridComboBoxColumn ItemsSource="{Binding LifeAreaList}" Header="Life Area"/>
<DataGrid.Columns>
</DataGrid>

DataGrid привязан к набору объектов типа Goal. Каждая цель имеет свойство типа LifeArea. Каждая LifeArea имеет свойства LifeAreaId и Name.

Контекст данных содержит наблюдаемую коллекцию Целей: GoalList и список Life Areas: LifeAreaList. Я хочу, чтобы пользователь мог выбрать другую область жизни для достижения цели. Также должно отображаться имя области жизни.

ИЗМЕНИТЬ


Решение состоит в том, что ItemsSource для DataGridComboBoxColumn должен быть установлен как статический ресурс. Другой вариант - установить ItemSource через код.

В конце концов я:

<DataGridComboBoxColumn x:Name="_lifeAreaComboBoxColumn" SelectedItemBinding="{Binding LifeArea}" DisplayMemberPath="Name" Header="Life Area">

В коде позади я устанавливаю ItemsSource:

_lifeAreaComboBoxColumn.ItemsSource = LifeAreaDAL.GetLifeAreas();

Когда я получу шанс, я преобразую его в StaticResource.

Ответы

Ответ 1

Вам нужно сделать что-то вроде этого (не стрелять в посланника):

<DataGridComboBoxColumn Header="Life Area" SelectedItemBinding="{Binding SelectedLifeArea}">
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding LifeAreaList}"/>
            <Setter Property="IsReadOnly" Value="True"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding LifeAreaList}"/>
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

Ответ 2

В дополнение к привязке вашего SelectedItem, я предполагаю, что ваше свойство SelectedLifeArea не получается непосредственно из LifeAreaList, поэтому при сравнении двух значений они возвращают false, даже если имя и идентификатор совпадают. Вероятно, вам необходимо перезаписать функцию .Equals объекта LifeArea, чтобы вернуть значение true, если идентификаторы обоих объектов соответствуют

public override bool Equals(object obj)
{
    if (obj is LifeArea)
    {
        return this.Id == (obj as LifeArea).Id;
    }
    return false;
}

Ответ 3

Up также может использовать DataGridTemplateColumn и просто вставить в него ComboBox, а затем подключить к нему соответствующие события.

<DataGridTemplateColumn Header="Alpha">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate DataType="models:MyModelDescription">
            <ComboBox ItemsSource="{Binding AlphaLevels, Mode=OneWay}" SelectedItem="{Binding Alpha, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"></ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>