The full XAML and code-behind are below. I have a Window with a DataGrid with a single column, a DataGridComboBoxColumn. In its EditingElementStyle I set the ComboBox-es editable and set their ItemsSource to the same collection to which I bind in the ElementStyle property. The bindings seem to work well until I run the program and try to change the value of a cell to another value. Although I currently select only from existing values (in future I want to allow entering custom items) the value is not saved and the previous value is shown after moving the focus.
If I put just this in the 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>
everything seems to be working.
<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");
}
}
}
}
Expected:
Actual: the user does the same steps as above, but when focusing another cell after selecting a new value, the previously focused cell remains with the initial value.
It seems that the TextBinding
is already with the Mode=TwoWay
. I just removed this line from the markup and everything works as expected:
SelectedItemBinding="{Binding Value, Mode=TwoWay}"