C#, WPF. I am using a Datagrid
with binding. My understanding is that with INotifyPropertyChanged
implemented, object properties should update in the Datagrid
if they are changed.
Currently this is not happening, although I I have implemented INotifyPropertyChanged
and I know from testing that the PropertyChanged
event is firing. My guess is that binding is not two-way(?) If that is the case I'm not sure how to set it to two-way. The binding is set in XAML
, and the ItemsSource
is set later in code-behind:
<DataGrid Name="dataGridxyz" ItemsSource="{Binding}">
dataGridxyz.ItemsSource = foo;
Adding two-way binding in XAML
using this syntax causes an error:
<DataGrid Name="dataGridxyz" ItemsSource="{Binding, Mode=TwoWay}">
So I was looking for something like this:
dataGridxyz.ItemsSource = foo;
dataGridxyz.Binding.Mode = TwoWay;
It may be that I could set it to two-way binding either in XAML
or code-behind... but I can't see how to do either.
EDIT:
The following is minimal functional example to show the problem. It is a much-simplified version of the real thing which is part of a much bigger project.
When the button is clicked, the Name
property is changed but it does not update in the PropertyGrid
.
<Window x:Class="testBinding.MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow">
<Grid>
<StackPanel Orientation="Vertical">
<DataGrid Name="dg" ItemsSource="{Binding}" AutoGenerateColumns="True"/>
<Button Name="btn" Width="100" Height="20" Content="Test" Click="btn_Click"/>
</StackPanel>
</Grid>
namespace testBinding
{
public partial class MainWindow : Window
{
BindingList<foo> bar = new BindingList<foo>() { new foo() };
public MainWindow()
{
InitializeComponent();
dg.ItemsSource = bar;
}
private void btn_Click(object sender, RoutedEventArgs e)
{
bar[0].Name = "Paul";
}
}
class foo : genericClass, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
class genericClass : INotifyPropertyChanged
{
private string _name = "John";
public string EyeColor = "Blue";
public bool Child = false;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string Name
{
get { return _name; }
set
{
_name = value;
MessageBox.Show("Name changed!"); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
OnPropertyChanged("Name");
}
}
}
}