Showing posts with label MVVM. Show all posts
Showing posts with label MVVM. Show all posts

Sunday, November 10, 2013

Collection Synchronization in WPF

I like the MVVM pattern in WPF. No doubt, it’s a perfect way to separate UI from logic. But you also get some other features out of the box when you apply this pattern. One of my favorites is binding collections to the UI and manipulating them with the use of a background thread. If you’re doing it right, you get a responsive UI while performing heavy background work without any additional effort required synchronizing the data to the view. WPF is just doing it for you.
 
Ok. That’s not 100% of the truth and of course it’s not that easy as it sounds. But there is not much to do. The data is coming from a background thread and it should be displayed in the UI thread. You know what that means? Correct. Someone has to dispatch the data to the UI thread. Luckily there’s a class called Dispatcher in WPF. Even better, you can use the Dispatcher anywhere in your WPF application because it provides a static property (Current) that gives you access to the current Dispatcher instance of the application. On the instance object you have the possibility to invoke any method on the UI thread you like, either synchronous or asynchronous. That was the preferred way until WPF 4.5. The problem was that it was not working in every case. Have you ever tried to modify an ObersableCollection from a background thread while it is bound to a ListView? The invoke methods on the Dispatcher won’t help you. With WPF 4.5 there’s a better and more comfortable approach to that problem: The EnableCollectionSynchronization method.

The EnableCollectionSynchronization method is a static method on the BindingOperations class in the System.Windows.Data namespace. The method has two overloads for controlling the access to the underlying collection from several threads (just have a look at http://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.enablecollectionsynchronization(v=vs.110).aspx). So, with this method you may just write something like the following in your view model
BindingOperations.EnableCollectionSynchronization(ListItems, lockObject);

where ListItems is your observable collection and lockObject is some object that will be used by the infrastructure to synchronize the access to the collection from different threads. The magic happens behind the scenes. The method is just a wrapper to some internal functionality enabling the underlying CollectionView to allow cross thread changes. If you want to know some more about WPF internals on handling views and collections you’re invited to read the next parts of the article, otherwise, if you just want to perform cross thread changes to collections bound to UI elements not worrying about how it works, then all relevant information has just been said.

WPF View Management
While using the new EnableCollectionSynchronization method I was wondering what happened behind the scenes when I use that method. In order to cure my curiosity I had a look into the framework and its internal classes. The key requirement of the WPF team was to allow the binding of one collection to many views without having strong references. Additionally the views should be able to sort, filter and navigate the collection without affecting other views or even the source collection itself. Because of those requirements the collection cannot manage its associated views and view management has to happen outside of the collection view relationship. That’s why there is a global ViewManager class that exists per application. This is an internal class with a static Current property. The view manager is just a dictionary that maps all bound collections to corresponding CollectionRecord objects.  The collection record is an internal utility class that keeps a weak reference to a view table and also has its own SynchronizationInfo. The ViewTable class is again a dictionary that manages CollectionViewSources and ViewRecords. Again, the view record acts as a utility class and encapsulates the access to the underlying CollectionView that is used by WPF for realizing sorting, filtering, grouping and navigation functionalities of collections on the UI. The collection view source is the XAML proxy of the collection view. The following picture shows the relationships between the mentioned classes.
 

When you call the EnableCollectionSynchronization method, the call is handled by the RegisterCollectionSynchronizationCallback method of the view manager, which in turn passes it to every collection view that belongs to the given collection. The CollectionView class contains an internal method SetAllowsCrossThreadChanges (see the following listing) which just sets a flag in the collection view whether to allow or deny cross thread operations on the underlying collection.
internal void SetAllowsCrossThreadChanges(bool value)
{
    bool flag = this.CheckFlag(
                    
CollectionView.CollectionViewFlags.AllowsCrossThreadChanges);
    if (flag == value)
    {
        return;
    }
    this.SetFlag(
         CollectionView.CollectionViewFlags.AllowsCrossThreadChanges, value);
    this.OnAllowsCrossThreadChangesChanged();
}


This flag is evaluated on binding operations (in our case changing the observable collection). The synchronization info on the collection record is used to synchronize the access the collection. This is where the two overloads of the EnableCollectionSynchronization come into play. The first one takes a lock object that is now used for synchronization. The second overload takes a callback that will be called during synchronization to handle the access among several threads. This provides the possibility for the client to manage the synchronization itself.

Monday, March 7, 2011

MVVM "In the Box"

Recently I found a really cool MVVM training kit that integrates with guidance directly into Visual Studio 2010. It targets WPF and was created by Karl Shifflett. The extension package can be found on the Visual Studio Gallery, so you can just install it into the IDE.
After installation there’s a new entry in the new projects wizard called “In the Box”. The template behind creates a new Visual Studio solution with a number of MVVM related projects. Additionally you get a guidance browser which can be used to display appropriate information to certain concepts and MVVM related topics. Within the projects you get some minimalistic samples that demonstrate the use of MVVM and concepts like IoC. The advanced examples rely on Prism and Unity as the dependency injection and IoC framework. Besides the sample application there’s a test project too, which shows how to write unit tests within Prism applications with the Visual Studio test runtime and Moq.
So if you want to learn MVVM quickly and get your hands on some practical examples, just give it a try.

Tuesday, December 7, 2010

MVVM in WPF - Code Division

Often I hear the discussion where to put certain code within the MVVM pattern in WPF to achieve loose coupling and reduce unnecessary dependencies. Frameworks like PRISM (or Composite Application Guidance for WPF), Caliburn, CoreMVVM and others try to address this problem in different ways. From speakers at conferences you may hear things like: “Never put any code in the code-behind file, except InitializeComponent.” Others make excessive use of code behind and leave the view model relatively dumb.
According to my experiences and beliefs you should always find the right balance of where to put what kind of code. For myself, I try to follow the undermentioned guidelines:

-         The View which consists of the XAML file and code-behind should never have a reference to its ViewModel. It should not even know the type of the view model (see my last blog entry on how to achieve this). Having said that it is evident that the ViewModel should not know the View it is bound to.
-         Communication between View and ViewModel takes place only by the use of Binding. Use Two-Way Binding if needed. Maybe use helper properties in the ViewModel. Implement INotifyPropertyChanged and use classes like ObservableCollection to notify the View of changes.
-         Code-Behind files may contain additional code if that code represents intrinsic functionality that can not or not easily be achieved by using Binding. An example might be the automatic update of a field according to another field in the View based upon a more complex calculation. You may also use Converters.
-         Use Commands to route events from the View to the ViewModel. Josh Smith made a really cool and lightweight CommandSink solution which uses RoutedCommands. The disadvantage in Josh’s example is that you need a type reference to your ViewModel in the View. But there are other solutions to avoid that (for those who are interested, you may download the BASTA 2010 example project from Tobias Richling).

In order to meet all of these guidelines you will need quiet some infrastructure in your application that produces some kind of overhead and may even have an impact on performance. So it is up to you to decide if’s worth to have that overhead.