如何使 ComboBox 列的编辑器元素保存用户选择的新值?

How to make the ComboBox column's editor elements save the user-selected new value?

完整的 XAML 和代码隐藏如下。我有一个 Window 和一个带有单列的 DataGrid,一个 DataGridComboBoxColumn。在它的 EditingElementStyle 中,我将 ComboBox-es 设置为可编辑,并将它们的 ItemsSource 设置为我在 ElementStyle 属性 中绑定到的同一集合。在我 运行 程序并尝试将单元格的值更改为另一个值之前,绑定似乎运行良好。虽然我目前 select 仅来自现有值(将来我希望允许输入自定义项目),但该值不会保存,并且在移动焦点后会显示之前的值。

如果我把这个放在 Window:

<StackPanel Orientation="Vertical">
    <ComboBox ItemsSource="{Binding Path=MyGroups,
                            RelativeSource={RelativeSource Mode=FindAncestor,
                            AncestorType={x:Type Window}}}" IsEditable="True"/>
    <ComboBox ItemsSource="{Binding Path=MyGroups,
                            RelativeSource={RelativeSource Mode=FindAncestor,
                            AncestorType={x:Type Window}}}" IsEditable="True"/>
</StackPanel>

似乎一切正常。

XAML

<Window x:Class="cs_wpf_test_11.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:cs_wpf_test_11"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="TestWindow" Height="450" Width="800">
    <Grid>
        <DataGrid Name="MyDataGrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="My only column"
                                        SelectedItemBinding="{Binding Value, Mode=TwoWay}"
                                        TextBinding="{Binding Value}">
                    <DataGridComboBoxColumn.ElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding Path=MyGroups,
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type Window}}}"/>
                        </Style>
                    </DataGridComboBoxColumn.ElementStyle>
                    <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="IsEditable" Value="True"/>
                            <Setter Property="ItemsSource" Value="{Binding Path=MyGroups,
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                AncestorType={x:Type Window}}}"/>
                        </Style>
                    </DataGridComboBoxColumn.EditingElementStyle>
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

代码隐藏

public partial class TestWindow : Window
{
    public ObservableCollection<ItemType> MyItems { get; set; }
    public ObservableCollection<string> MyGroups { get; set; }
    public TestWindow()
    {
        InitializeComponent();
        MyGroups = new ObservableCollection<string>();
        MyGroups.Add("test");
        MyGroups.Add("test 2");
        MyItems = new ObservableCollection<ItemType>();
        MyItems.Add(new ItemType()
        {
            Value = "test"
        });
        MyItems.Add(new ItemType()
        {
            Value = "test 2"
        });
        MyDataGrid.ItemsSource = MyItems;
    }
}

public class ItemType : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    protected string _Value = "";
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            if (_Value != value)
            {
                _Value = value;
                OnPropertyChanged("Value");
            }
        }
    }
}

预期:

  1. 用户select是一个小区,
  2. 进入其编辑模式(通过双击或 F2)和
  3. selects 从下拉菜单中选择与之前显示的值不同的另一个值。
  4. 用户将 selected 单元格更改为另一个
  5. 并且先前获得焦点的单元格仍保留有新的 selected 值。

实际:用户执行与上述相同的步骤,但是在select输入新值后聚焦另一个单元格时,先前聚焦的单元格仍保持初始状态值。

看来 TextBinding 已经和 Mode=TwoWay 在一起了。我刚刚从标记中删除了这一行,一切都按预期工作:

SelectedItemBinding="{Binding Value, Mode=TwoWay}"