Bind Model to Winforms DataGridView, can not get old value when property changed
See original GitHub issue.NET version
.Net 8.0 Preview 4
Did it work in .NET Framework?
No
Did it work in any of the earlier releases of .NET Core or .NET 5+?
No response
Issue description
I have a Model (INotifyPropertyChanged) and bound to a DataGridView by BindingList, Once I edited a property of model instance, DataGridView’s cell value updated before PropertyChanged raied. I have no idea why.
I am going to listen to BindingList’s ListChanged (ItemChanged) event and get new value and old value of updating property, but DataGridView’s cell value updated before raising this event, so that I can not get old value from DatGridView’s cell.
Does anyone has some others solution to get both of new and old values when model’s property changed? Great thanks!
Steps to reproduce
Here is my code:
public partial class Form1 : Form
{
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected bool SetProperty<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<TValue>.Default.Equals(field, newValue))
{
return false;
}
var dataGridView = Application.OpenForms.OfType<Form1>().First().dataGridView1;
if (dataGridView.RowCount > 0)
Debug.Print($"Before set value to field: {dataGridView.Rows[0].Cells[0].Value}");
field = newValue;
if (dataGridView.RowCount > 0)
Debug.Print($"After set value to field But before raise PropertyChanged event: {dataGridView.Rows[0].Cells[0].Value}");
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (dataGridView.RowCount > 0)
Debug.Print($"After raise PropertyChanged event: {dataGridView.Rows[0].Cells[0].Value}");
return true;
}
}
public class Model : BindableBase
{
private int age;
public int Age { get => age; set => this.SetProperty(ref this.age, value); }
}
BindingList<Model> Models = new();
public Form1()
{
this.InitializeComponent();
this.dataGridView1.AutoGenerateColumns = true;
this.dataGridView1.DataSource = this.Models;
this.dataGridView1.Click += this.DataGridView1_Click;
}
private void DataGridView1_Click(object? sender, EventArgs e)
{
switch (this.dataGridView1.RowCount)
{
case 0:
this.Models.Add(new Model() { Age = 10 });
break;
default:
this.Models[0].Age = DateTime.Now.Microsecond;
break;
}
}
Here is some logs, you can see that Cell value was updated when set value to field and before raising PropertyChanged event;
Before set value to field: 10
After set value to field But before raise PropertyChanged event: 478
After raise PropertyChanged event: 478
Before set value to field: 478
After set value to field But before raise PropertyChanged event: 744
After raise PropertyChanged event: 744
Issue Analytics
- State:
- Created 3 months ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
Why listbox and datagridview does not update
Hi, I am relatively new to C# and am learning WindowsFormApp at the moment. My questions are related to listbox and datagridview please....
Read more >Data Binding in Windows Forms DataGrid (SfDataGrid)
WinForms DataGrid control is designed to display the bounded data in a tabular format. ... event is raised when the DataModel property value...
Read more >A Detailed Data Binding Tutorial
Demonstrates a variety of Windows Forms data binding features through several simple examples.
Read more >Wpf datagrid cell events. It also occurs when the user ...
Now you know which item the user has selected (clicked on). Make that property = PropertyChanged and use the setter for the updated...
Read more >Professional C# 4.0 and .NET 4 - Page 1128 - Google Books Result
If the values in the list are wide, you can change the width of the drop-down ... however, the DisplayMember and ValueMember properties...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

I don’t think there is anything wrong in this behavior: the DataGridView does not store a copy of your value, he just use the model’s value when asked, so when you call
dataGridView.Rows[0].Cells[0].Value, the datagridview callsModel.Ageon your model, which returns the new value since you just updated the field.The only goal of this event is to indicate the control that the value has been updated “recently”, and that the control should reread the value and update its display accordingly (for example). There is no concept of previous/new value.
INotifyPropertyChanging was added for this exact case: if you need to get the previous and the new value, then you have should implement and subscribe to this event.
In my opinion, storing a value before/after change should be handled by your model directly (like storing the previous value in a different field, exposed as a “PreviousAge” property for example), and not depending on the datagridview, the UI, or the databinding engine itself.
We got the same result as the code provided in this issue. But needs our engineering team to look into it about codes.