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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3563325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:03:43  来源:igfitidea点击:

How to Bind data to DataGridComboBoxColumn in DataGrid using MVVM

wpfmvvmdatagriddatagridcomboboxcolumn

提问by GoalMaker

This is driving me crazy. I have a DataGrid which has a DataGridComboBoxColumn which I want the user to be able to use to select from. This is the basic outline of my grid.

这真让我抓狂。我有一个 DataGrid,它有一个 DataGridComboBoxColumn,我希望用户能够使用它进行选择。这是我的网格的基本轮廓。

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

The DataGrid is bound to a collection of objects of type Goal. Each Goal has a property of type LifeArea. Each LifeArea has the properties LifeAreaId and Name.

DataGrid 绑定到目标类型的对象集合。每个目标都有一个 LifeArea 类型的属性。每个 LifeArea 都具有 LifeAreaId 和 Name 属性。

The data context contains an observable collection of Goals: GoalList and a list of Life Areas: LifeAreaList. I want the user to be able to select a different life area for a goal. Also the name of the life area needs to be the displayed value.

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

EDIT

编辑



The solution is that the ItemsSource for the DataGridComboBoxColumn has to be set as a static resource. Another option is to set the ItemsSource through code.

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

In the end I have:

最后我有:

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

In the code behind I set the ItemsSource:

在后面的代码中,我设置了 ItemsSource:

_lifeAreaComboBoxColumn.ItemsSource = LifeAreaDAL.GetLifeAreas();

When I get a chance I'll convert this to a StaticResource.

当我有机会时,我会将其转换为静态资源。

回答by Kent Boogaart

You need to do something like this (don't shoot the messenger):

你需要做这样的事情(不要射击信使):

<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>

回答by Rachel

In addition to binding your SelectedItem, I am guessing that your SelectedLifeArea property is not obtained directly from LifeAreaList so when comparing the two values they are returning false, even if the name and id match. You probably need to overwrite the .Equals function of the LifeArea object to return true if the Ids of both objects match

除了绑定您的 SelectedItem 之外,我猜测您的 SelectedLifeArea 属性不是直接从 LifeAreaList 获得的,因此在比较两个值时,它们返回 false,即使 name 和 id 匹配。如果两个对象的 Id 匹配,您可能需要覆盖 LifeArea 对象的 .Equals 函数以返回 true

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

回答by Joshua

Up can also use a DataGridTemplateColumn and just put a ComboBox in it and then wire the appropriate events to it.

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>