How do I update an ObservableCollection item's property from change in a WPF DataGrid?
Solution 1
CollectionChanged is for Insert and Delete. NotifyPropertyChanged is for update of an items. In the posted code you don't actually implement INotifyPropertyChanged.
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
And I think it is cleaner to bind to a public property where you return _itemDataCol
Otherwise the TwoWay answer of celopez3
Solution 2
An ObservableCollection
doesn't listen to its items' INotifyPropertyChanged
events; use a BindingList
instead.
In other words, [an
ObservableCollection
] only notices when items are added or removed, not when the values of its items change, even if those items implement INotifyPropertyChanged. In comparison, a BindingList DOES listen to INotifyPropertyChanged, and therefore, if its items are modified, the changes will be reflected in the grid. As a result grouping, sorting, and statistical functions will be updated.
K J
Updated on July 09, 2022Comments
-
K J almost 2 years
I have a WPF DataGrid who's data source is an ObservableCollection. It is set up loosely as the following:
public class ItemDataCollection : ObservableCollection<ItemData> { } public class ItemData : INotifyPropertyChanged { private bool _selected = true; public bool Selected { get { return _selected; } set { if (value != _selected) { _selected = value; NotifyPropertyChanged("Selected"); } } } } _itemDataCol = new ItemDataCollection(); <... fill the _itemDataCol with data here ...> dataGrid1.ItemsSource = _itemDataCol;
When the collection is updated, a dataGrid1.Items.Refresh() updates dataGrid1 nicely. However when I modify the "Selected" property of a row by checking or unchecking the checkbox in the row corresponding to that property, the item in the collection does not get updated. I looked into the CollectionChanged event of the ObeservableCollection, but that is not appearing to get triggerd. What wiring do I need to get the dataGrid1 to update the collection.
Update
All I was doing was setting the ItemSource property to the ObservableCollection and letting the columns auto-generate. I have since changed to bind directly, and found more detail to the problem. When I simply check the box - no notification is triggerd. However if I hit after checking the box, then the collection is updated. Here is the binding:
<DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay}" Header="Selected"></DataGridCheckBoxColumn>
So I guess the question is how do I get the update with having to hit after checking or unchecking the box?
Update #2 (I cannot answer as my rep is not high enough yet) OK - I think I have the solution. If I include "UpdateSourceTrigger=PropertyChanged" in the binding everything seems to work.
<DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Header="Selected"></DataGridCheckBoxColumn>
Please leave comments if there are any negative affects of this that I may be missing. Thanks for the help!
-
K J about 12 yearsSorry - I omitted the implementation of NotifyPropertyChanged to keep the post short. It is implemented correctly in my actual code.
-
paparazzo about 12 yearsDoes it get called? Does set get called? Please try binding to a public property. If all that fails try bypassing you ItemDataCollection and supply a ObservableCollection<ItemData> directly (for testing).
-
K J about 12 yearsAll I was doing was setting the ItemSource property to the ObservableCollection and letting the columns auto-generate. I have since changed to bind directly, and found more detail to the problem. When I simply check the box - no notification is triggerd. However if I hit <enter> after checking the box, then the collection is updated. Here is the binding: <DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay}" Header="Selected"></DataGridCheckBoxColumn> Any ideas?
-
K J about 12 yearsI tried the following: <DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay}" Header="Selected"></DataGridCheckBoxColumn> Selected is public. The problem turns out that if I hit <enter> after checking or unchecking the box, the ObservableCollection is updated. Simply checking the box does is not enough to trigger the update however.
-
paparazzo about 12 yearsYou need to set the UpdateSourceTrigger to PropertyChanged msdn.microsoft.com/en-us/library/…
-
K J about 12 yearsI was messing with the site - still new to posting on it. When I noticed it unchecked yours, I re-accepted but it didn't take. It was not my intention - you earned the accepted answer.
-
paparazzo about 12 yearsThat is strange as it shows you both accepted and unaccepted today. The answer shows a check mark but I did not get credit. Please try a single click on the check mark. And if I don't get credit then no problem. Good you got it working.
-
K J about 12 yearsHmm. I tried unaccepting and accepting again. It does show your post as the accepted answer - at least in my browser on different machines. My apologies - you were the first to post and the credit should be yours. That is what I get for playing with something that was not broken...
-
paparazzo about 12 yearsDid you try to accept your answer? I bet that is what killed my answer.