How DataGrid is notified when item in the collection is changed? - wpf

I have two DataGrids bound to the same ObservableCollection property in my ViewModel.
When I edit an existing row in one DataGrid another gets updated after row is commited.
But how it works? The NotifyCollectionChanged event is not raised on the underlying ObservableCollection. I have checked it by subscribing to the event.

In this case, you are modifying the properties of the item (entity) of the collection, not the collection itself.
Therefore, the CollectionChanged event is not raised.
To update properties in an entity, INotifyPropertyChanged must be implemented in it.
But if the change of properties happens ONLY through bindings, then even this is not necessary.
Bindings use PropertyDescriptor and other types of reflection in their work.
This allows bindings to "know" that a property has been changed by another binding.
If you speak Russian, read my article: https://www.cyberforum.ru/wpf-silverlight/thread2650880.html

Related

NotificationObject update all properties on reference re-assignment

When your view entity derives from NotificationObject and each property calls the "RaiseProperty" change in its setter, will all properties call "RaiseProperty" on object reassignment. Or do you have set each property manually when you want to notify WPF controls of property changes.
Ex.
Item/entity arrives from WCF.
Item that is already in an observable collection detects that the arrived item is already contained in the collection and should check for any properties that are different between item already in collection and item that arrived from WCF.
Can I do this?
EntityInCollection = EntityFromWCF and have each property raise its event? Or do I have to do this:
EntityInCollection.Property1 = EntityFromWCF.Property1... etc. for each property.
I have a gridview diplaying object and would like to animate the cells that get updated but I'm thinking that reassigning the reference will raise all events and not simply the ones that have changed/are different between the two objects.
Thanks
If you're replacing the entire object, the ObservableCollection will raise an event to notify of this change. UI components will (or should - I can't vouch for all controls, especially 3rd party ones) respond and refresh automatically.

List<> collection does not update the View in MVVM

I used the List<Person> collection as the ItemsSource for the DataGrid control.
But it did not update the View if i remove the item from the List collection. I was struggling for a long time for the solution.
Then Instead of the List<Person> collection in my ViewModel. I changed this into ObservableCollection<Person> collection. Now it updates the view when ever there is a change in the collection.
I am not sure why it updates only for ObservableCollection<Person> ? Anyone ?
Well its in the name. A simple List doesn't tell the ui to update, in other words "the view can't observe the list". There is no weird magic behind Databinding. WPF and DataBinding needs the Data model to tell them "this is new" or "this is changed", you propably already saw INotifyPropertyChanged, INotifyCollectionChanged is the same but for collections, and the List<> doesn't implement it, ObservableCollection does.
Because List does not implement INotifyCollectionChanged
Because the update of a databinding is not a kind of magic, there are several requirements to make databinding working correctly. If you have a single property to bind on this property must be either a dependency property or its parent class must implement the INotifyPropertyChanged interface to notify the wpf binding system about changes of the property value.
For a collection there is a simelar mechanism: it must implement INotifyPropertyChanged to inform the wpf binding system about removed/moved/added items.
See here for more details: http://msdn.microsoft.com/en-us/library/system.collections.specialized.inotifycollectionchanged.aspx
ObservableCollection<T> fires change events every time you change the items in the collection. List<T> doesn't. That's the reason.
DataBinding is lazy. If you don't tell your view that something has changed, it won't bother updating. Under the hoods, WPF DataBinding registers for change notifications, so that your ViewModel can tell the view when it has changed. It does this with interfaces like INotifyPropertyChanged and INotifyCollectionChanged.
ObservableCollection<T> implements the interface INotifyCollectionChanged. This interface defines the event CollectionChanged, which your View basically attaches its own event handler to. That handler will update the view when the event is raised by the collection.

WPF MVVM: Notifying the View of a change to an element within an ObservableCollection?

Calling OnPropertyChanged for an ObservableCollection only works when there has been some change to the properties of the collection, not the objects it contains (add, remove, clear, etc).
Is there any way to notify the View that there has been a change to an item within the collection?
The objects it contains have to implement INotifyPropertyChanged as well. In your setter you trigger the event, and WPF will pick up on this and read in the new value as long as you are using two-way bindings or read-only bindings.

ObservableCollection DataGrid

I bound the ObservableCollection to the dataGrid itemssource.
the collectionChangedEvent of the observable Collection is getting called only when we add, delete, remove. But not firing when we update the record.
how to fire the event for Update too?
If you want to be notified when an item is changed (ie you want to subscribe to this event), you are out of luck with ObservableCollection<T> because this collection only fires the CollectionChangedEvent.
Indeed, if you implement INotifyPropertyChanged, you will see changes to the items in the view (WPF does this automatically), but if you need to execute manual actions when an item changes, you can use BindingList<T>.
For exactly this scenario I rolled out a custom BindableCollection<T>, which implements ObservableCollection<T> and adds the OnItemChangedEvent. I can provide some sample code if necessary...
The collection doesn't know when the record is modified. To get a notification when this happens, the record needs to implement INotifyPropertyChanged

How do I BringToView the latest item added to a bound ObservableCollection

I have a silverlight control (View) which displays a list of items in a specified property of the datacontext (viewmodel).
What I need is for the scrollviewer in my control to scroll to the top or bottom depending on where the latest item has been added to the list. (It'll always be either the beginning or the end of the list, I don't need to worry about middle of list insertions.)
In WPF i'd just use the DataContextChanged event to start listening to the viewmodel, but in silverlight that event is internal.
Any ideas on how to tackle this?
A good starting point is Attached Behaviors on CodeProject.
A useful behavior would watch the ListBox.ItemsSource and attach to the observable collection when set. On the collection changed event, use ListBox.ScrollIntoView to display the changed item.
I can't use the CollectionChangedEvent of ObservableCollection since I need the DataContextChanged event to get the DataContext which holds the Collection in the first place.
Would you not do this in the ViewModel?
Whatever ViewModel has the ObservableCollection, expose a property of type T named SelectedItem and whenever the ObservableCollection changes with a new item, the CollectionChanged event will allow you to set the SelectedItem property. Once this is done, wire up the SelectedItem in the control to this property on your ViewModel.
This will obviously only work with controls like ListBox where a SelectedItem property exists.
In place of DataContextChanged in WPF , you can use CollectionChanged event of ObservableCollection. In the collection changed you will get to know the NewItem Index.

Resources