如何使用MVVM绑定数据到DataGrid中的DataGridComboBoxColumn?

15

这让我抓狂。我有一个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的对象集合,每个Goal具有一个类型为LifeArea的属性。每个LifeArea都有LifeAreaId和Name属性。

数据上下文包含一个可观察的目标集合(GoalList)和一个生活领域列表(LifeAreaList)。我希望用户能够为目标选择不同的生活领域。此外,生活领域的名称需要成为显示值。

编辑


解决方法是将DataGridComboBoxColumn的ItemsSource设置为静态资源。另一种选项是通过代码设置ItemsSource。

最终结果如下:

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

在代码后台,我设置了ItemsSource:

_lifeAreaComboBoxColumn.ItemsSource = LifeAreaDAL.GetLifeAreas();

我有机会的话,我会把这个转换为静态资源。


你的 DataGridComboBoxColumn 中不需要 DisplayMemberPath 吗? - Neil Knight
我已经尝试过了,但是下拉菜单中没有显示任何东西。 - GoalMaker
不是说这样就能解决问题,但是 GridComboBoxColumn 怎么知道哪个生活领域被选中了呢?你也需要将 SelectedItem 绑定到某个东西上。 - Kent Boogaart
你是否检查过是否存在绑定错误并且PropertyChanged是否被触发? - Prince Ashitaka
3个回答

22
你需要做类似这样的事情(别怪我说出来):
<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>

1
哦,太感谢了!!!我已经试图寻找这个解决方案三周了。为什么DataGrid中的ComboBox如此奇怪?为什么它没有按照你所期望的逻辑树来进行?我的意思是,DataGrid在成为.NET 4.0的一部分之前已经是beta版本很长时间了。他们为什么不修复它呢?我对这些事情感到担忧,我想知道我该如何学习这些东西?我需要阅读哪些内容才能找到这个特定问题的解决方案?请问您是如何解决这个问题的? :D - Houman
1
我需要为ComboBox样式添加DisplayMemberPath和SelectedValuePath的setter。 - JGeerWM

1

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>

1

除了绑定你的SelectedItem之外,我猜测你的SelectedLifeArea属性不是直接从LifeAreaList中获取的,因此当比较这两个值时,即使名称和ID匹配,它们也会返回false。你可能需要重写LifeArea对象的.Equals函数,以便在两个对象的ID匹配时返回true。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接