Как привязать данные к 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>