WPF数据网格中的ComboBox数据绑定/更新不起作用。

10
如果我在Visual Studio 2010中设置一个新的WPF应用程序并添加以下代码+XAML,将打开一个带有组合框的数据网格。现在的问题是,通过组合框更改值不会传播到绑定的数据模型中。换句话说:名为MyValue的属性从未被设置。我已经花了几个小时了,但不知道为什么这不起作用。还有许多类似的线程和建议也没有用。
这里是XAML。它只是一个包含DataGrid的简单窗口。DataGrid具有一个模板列,其中设置了CellTemplate和CellEditingTemplate。两者都包含一个ComboBox,该ComboBox使用资源部分中的列表进行填充。ComboBox.SelectedItem绑定到MyItem.MyValue:
<Window x:Class="DataGridComboBoxExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"    xmlns:local="clr-namespace:DataGridComboBoxExample">

    <Window.Resources>

        <local:MyItemList x:Key="ItemList"/>

        <DataTemplate x:Key="NotificationModeDataTemplate">
            <ComboBox
                ItemsSource="{StaticResource ItemList}"
                SelectedItem="{Binding Path=MyValue, Mode=OneWay}" />
        </DataTemplate>
        <DataTemplate x:Key="NotificationModeEditTemplate">
            <ComboBox
                ItemsSource="{StaticResource ItemList}"
                SelectedItem="{Binding Path=MyValue, Mode=TwoWay}" />
        </DataTemplate>

    </Window.Resources>

    <Grid>
        <DataGrid x:Name="myDataGrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn
                    Header="Test" Width="100"
                    CellTemplate="{StaticResource NotificationModeDataTemplate}"
                    CellEditingTemplate="{StaticResource NotificationModeEditTemplate}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

这里是代码。它包含了主窗口的构造函数,它只是设置了 DataContext。MyItem 是行数据模型,支持 INotifyPropertyChanged。MyItemList 是绑定到 ComboBox.ItemsSource 的选项列表。

以下是翻译后的内容:

这段代码包括主窗口的构造函数,该函数仅设置了 DataContext。MyItem 是行数据模型,支持 INotifyPropertyChanged 接口。MyItemList 是绑定到 ComboBox.ItemsSource 的选项列表。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        myDataGrid.ItemsSource = new List<MyItem> 
        {
            new MyItem { MyValue = "i0" },
            new MyItem { MyValue = "i1" },
            new MyItem { MyValue = "i0" },
        };
    }
}

public class MyItem : INotifyPropertyChanged
{
    public string MyValue
    {
        get { return myValue; }
        set
        {
            myValue = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("MyValue"));
            }
        }
    }
    private string myValue;

    public event PropertyChangedEventHandler PropertyChanged;
}

public class MyItemList : List<string>
{
    public MyItemList() { Add("i0"); Add("i1"); Add("i2"); }
}
1个回答

19

我怀疑您需要使SelectedItem绑定在属性更改时更新源,以使其起作用。

SelectedItem = "{Binding Path = MyValue,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}"

在调试此问题时,我建议将CellTemplate和CellEditingTemplate都引用您的编辑模板,以消除其他不相关的模板,直到您解决问题为止。


1
我刚刚测试过了,对我有效。我让CellTemplate和CellEditingTemplate都引用编辑模板,并添加UpdateSourceTrigger=PropertyChanged。当我在下拉框中选择一个项目时,会调用MyValue setter。我的测试环境是安装了VS 2010 SP1的.NET 4.0。 - Josh Smith
3
为什么这个方法管用呢?如果我将同样的 ComboBox 移到 DataGrid 外面(作为一个列表),那么对于相同的 ViewModel,就不需要这个方法了。 - Simon_Weaver

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