Does WPF-DataBinding support asynchronous updates - wpf

I changed accidentally the value of a BusinessObject-property that implements INotifyPropertyChanged from within a BackgroundWorker (BackgroundWorker.DoWork).
Amazingly, this led not to an error but actualized the text of the TextBlock that was bound to the property without any complaint.
Is the execution of asynchronous bindings part of the WPF binding engine or is this only a special case where the CheckAccess-test have been forgotten or ommited due to other considerations.

Bindings on scalar properties support updates from other threads, so you don't need to call Dispatcher.Invoke when updating a property of the model (or ViewModel). However, this is not true for binding to a collection: if you have a ItemsControl bound to an ObservableCollection<T>, changes to this collection must be done on the UI thread, as CollectionChanged events are not automatically forwarded to the UI thread. Alternatively, you could use a variant of ObservableCollection<T> that raises the event on the UI thread (here's a implementation)

Related

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

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

Why WPF binding handles INotifyPropertyChanged in two different ways?

I recently find out that wpf handles INotifyPropertyChanged in two different ways. I just wanna know what's the reason.
Let us take a normal twoway binding with validation true.
if you set a property from ui to viewmodel it goes like this.
setter call started
value set
INotifyPropertyChanged started
INotifyPropertyChanged done
setter done
getter called and done
IDataErrorInfo called and done
but if you set the property in your viewmodel it goes like this
setter call started
value set
INotifyPropertyChanged started
getter called and done
IDataErrorInfo called and done
INotifyPropertyChanged done
setter done
Changing property from UI to ViewModel may lead to deadlock kind of situation which might run into end less recursive calls in two way scenarios. In order to block this from happening, when WPF is making change to model, it will continue to track changes via INotifyPropertyChanged ,but this change will be queued in dispatcher queue, and it will be executed after its current update is finished.
Since the change in viewmodel is not initiated by WPF, WPF will not queue the operation, it will immediately execute the change.

Initiate change of a DependencyProperty of a ViewModel with a Event of another Thread

I want to change a DependencyProperty of my ViewModel from a class which connects the application to a database.
This class raises events which should initiate a change of some properties in my ViewModel.
How can I realize that? I don't have the Dispatcher of the View.
I'm assuming you don't really have dependency properties on your viewmodels but rather normal C# properties which raises the PropertyChanged event.
If so, you should be fine already. Modify your properties from your background thread (normal concurrency issues apply obviously) and when they are bound to a WPF element's Dependency Property the runtime system will take care of marshalling the change to the proper thread (by using the view's Dispatcher object)
This works for normal properties, I'm not sure it works for ObservableCollections.
There are also different approaches for doing the marshalling inside the viewmodels. The simplest way is to just store the value of Dispatcher.CurrentDispatcher in your viewmodel's constructor. This works as long as your viewmodels are created on the UI thread.
One immediate solution to the problem is to capture the view's Dispatcher and store it on the view model when you create it, so you can Invoke/BeginInvoke the change to it in response to the event.
That being said, you should consider making your viewmodels use INotifyPropertyChanged with CLR properties rather than DependencyProperties to avoid issues like this. That way, any thread can make changes to your viewmodel and have the results reflected in the view.

Does databinding always marshal to the UI thread?

When binding to a property in Silverlight 3 and 4, the Windows Phone 7 version silverlight and in WPF 3.5 and 4 will property change notifications always be marshalled to the UI thread? Are you aware of any scenario where I can not rely on that and would have to do the marshalling in my code?
I did some experiments...
INotifyPropertyChanged
If you make a change to a property from a background thread, and it fires INotifyPropertyChanged from that background thread, and the property is databound, then...
WPF: it works (i.e. the databinder marshals it to the UI thread)
Silverlight5 and WinRT: it fails (i.e. the databinder doesn't marshal)
Phone: I assume it's the same as Silverlight, but haven't tried.
DependencyProperty
What if the property is a dependency property rather than INotifyPropertyChanged? What if you alter this property from a background thread? Well, I haven't done any experiments, but I read that it doesn't do any marshalling.
INotifyCollectionChanged (e.g. ObservableCollection)
If you add/remove elements in an ObservableCollection from a background thread, and the collection is databound to a listbox or similar, then what happens?
WPF: As of WPF4.5, you can use BindingOperations.EnableCollectionSynchronization(collection, new object()); and it will marshal correctly. However, prior to WPF4.5, it's as Pavlo said.
Silverlight, WinRT: again the same as Pavol said.
Yes, collections. When you bind to an observable collection and you change it from a non-UI thread you will get an exception. You will have to marshal the collection change to the UI thread.

WPF: Bindings - Object not updated

I have a an object which is set to the DataContext in a Window. I have textboxes in the window which are bound to the properties on the object. There seems to be a delay however before the properties on the object are updated.
<TextBox x:Name="txtPropertyOne" Text="{Binding Path=PropertyOne,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
If I change the values in a few textboxes then quickly try to access the properties to which they map, sometimes there are changes which aren't reflected in the properties of the object. I thought that was what the PropertyChanged UpdateSourceTrigger was supposed to take care of.
If I change the values in a few
textboxes then quickly try to access
the properties to which they map
I can interpret this statement in two ways:
You're trying to access the values on a background thread. In that case, you may be accessing the properties before the UI thread has had a chance to do its thing.
You're using a separate message on the UI thread to check the values. Bindings are updated at a priority lower than Send and Normal. So if your message is priority Send or Normal it will be processed before any pending binding updates.
If this doesn't answer your question, please clarify what you mean by "quickly trying to access the properties".
The basic rule of WPF Databinding is simple:
The target property must be a
dependency property, and you're
already correct, it's bound to Text
property of TextBox.
The source property can be a CLR
object (other than any derived WPF's
DependencyObject), but the object
must employ or implement its own
INotifyPropertyChanged.
Have you you already implemented INotifyPropertyChanged on your object?

Resources