Orchestrating Animated Transitions between View and ViewModel

April 25, 2009

Introduction

When working with the Model-View-ViewModel (MVVM) pattern, the data shown in a View is almost always transferred to it via data binding.  Changes made to properties on a ViewModel object immediately propagate to the binding targets in the View.  This is normally a good thing.  Sometimes, however, the immediacy of the propagation can be a problem.

Why would you want a new property value to not immediately show up in the UI?  Well, suppose you want to display an animated transition between the old value and the new value.  If the new value immediately shows up in the View, you won’t have a chance to animate “out” the old value before animating “in” the new value.   For example, suppose the property’s value is a page of data items to show in a list.  If we want to fade away the first page of items before fading in the new page of items, we need to start the fade-away animations before the new page of items is displayed.

This is the type of problem that the Visual State Manager (VSM) solves.  Since the VSM is not yet part of WPF proper (it won’t be until .NET 4.0), we cannot make use of it yet in production applications.  Also, the VSM is designed to be used inside of custom controls, so it is not exactly equivalent to what we are going to explore below.

The AnimatedTransition Class

I faced this exact problem many times while working on WPF and Silverlight applications.  After experimenting with several approaches to coordinating property changes with animated transitions, I started to understand the core problem more clearly.   Yesterday I listened to this incredible rendition of the Scherzo from Mendelssohn’s “A Midsummer’s Night Dream” and was hit by a flash of inspiration.  I realized a way to create a simple, type-safe, reusable way of having a ViewModel and View work together to create animated transitions between two property values.  The AnimatedTransition class was born!

AnimatedTransition

An instance of AnimatedTransition can be embedded in any ViewModel class.  The View(s) that need to perform transitions must access the AnimatedTransition object and hook one or more of its events in order to know when transitions should start.

The Demo App

In the demo app, which is available at the bottom of this post, there is an ItemsControl that displays four Hello Kitty images per “page,” as seen below…

kitty kats

When the user navigates to a different page, via the circles below, the old kitties fade away and then the new ones fade in.

We are not going to examine all of the classes involved in making this little app work.  If you want to get a high-level understanding of the ViewModel classes, click on this class diagram to view it at full size:

class diagram

The current page of kitties to show in the ItemsControl is contained in SelectedPage property of KittyKatTerraceViewModel.  Since we need to have a transition between the two values of that property, we use an AnimatedTransition to enable that.  Here is how KittyKatTerraceViewModel uses and exposes an AnimatedTransition:

animated transition creation

When the user clicks on a little circle beneath the ItemsControl to select a page, this method in the PageOfKittyKatsViewModel class executes:

starting a transition

All of the relevant logic in the KittyKatTerraceView control’s code-behind is listed below.  This shows how a View can consume and interact with an AnimatedTransition object.

transition usage

It’s important to note that you must attach a handler to the Completed event of the Storyboard that fades away the old items.  When the event is raised, the AnimatedTransition must be told to finish transitioning to the new value, and actually apply the value.  That is accomplished by calling the Finish() method.  Once the new value has been applied, the AfterApplyNewValue event is raised, at which time you can fade in the new items.

You can download the source code here.  Note: Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Starting my new life at IdentityMine

April 20, 2009

I am very proud, and excited, to announce that I will soon join IdentityMine as a Senior UX Developer!  IdentityMine specializes in designing and developing excellent user experiences via technologies like WPF, Silverlight, and Microsoft Surface.   The firm is very well-known and respected in the Microsoft Client App Dev space, so I’m thrilled to join their ranks and help build awesome applications.

Despite my excitement over this new opportunity, I must admit that I will miss working at Infragistics.  I am leaving behind a lot of talented, friendly, energetic people there, and wish the best for all of them.   Sometimes in life, you just “gotta do what ya gotta do.”  This is one of those times for me.

I have a one-way ticket to Seattle for tonight.  See you there…


A Mediator Prototype for WPF Apps

April 6, 2009

UPDATE: For a fully featured and tested Mediator implementation, check out the Messenger class in my MVVM Foundation library.

This blog post shows a prototype implementation of the Mediator design pattern, intended to be used in WPF and, possibly, Silverlight applications.  The Mediator class can be used to provide loosely-coupled message-based communication between various entities, such as ViewModel objects.  The prototype was inspired by this thread on the WPF Disciples group, and particularly by conversations I had with Marlon Grech.  I am posting this prototype on my blog, in hopes of receiving suggestions and new ideas on how to improve the design.
The code reviewed in this blog post works, but is not complete or intended to be used in production applications.

Creating a class that allows various objects to send messages to each other is trivial.  It becomes more challenging when you try to create a reusable class like that which does not leak memory.  Since the Mediator object can live indefinitely, but the objects registered to receive messages might have a shorter lifespan, this could easily become a hotspot for memory leaks to occur.  In an ideal world, any object that registers itself to receive messages should unregister itself when it no longer needs to receive messages.  However, in practice, it’s not always easy to know when an object should unregister itself.  The design of the Mediator class needs to take this into consideration.

Let’s take a quick look at how this Mediator class might be used.  Here’s some code showing how an object registers itself to receive a certain message…

registration

Notice that registering for a message requires you to pass in two parameters.  The first parameter is a unique identifier for that message, in this case a string exposed by the MediatorMessages class.  The second parameter is a delegate of type Action<object>.  In the example above I use a lambda expression to create the delegate, but you could just as easily create a new Action<object> instance, if you’d prefer.

Here is an example of an object sending its colleagues a message:

notification

So far, so good, so it seems.  However, there is a problem.  A delegate, such as Action<object>, stores a reference to the object on which the target method should be invoked.  When you pass that delegate to the Mediator, it stores the delegate in a collection, for later use. If you never remove the delegate from the Mediator, via unregistering (which is something I have yet to implement in the prototype), the registered object will never be eligible for garbage collection since there will be a hard reference to it.  Hence, the memory leak issue I mentioned earlier.

My first thought was to store a reference to the Action<object> in a WeakReference.  Since the Garbage Collector will throw away objects that are referenced only by WeakReference objects, it would seem that this would do the trick.  Unfortunately, it’s not that simple.  The problem with that approach is that the GC will throw away the Action<object> instance because it is only being referenced by a WeakReference!

Marlon came up with a great idea, which borrows Greg Schechter’s idea of subclassing WeakReference to make a “weak delegate.”  This is essentially a delegate that uses a WeakReference to store a reference to the target object, instead of using a normal object reference, as normal delegates do.  The drawback to Marlon’s great idea is that it relies on the use of reflection to invoke the target method on the colleague.  This means that it will have a performance decrease, and won’t run in partial trust.

I took Marlon’s idea, and refined it so that it does not require the use of reflection (at least, not directly).  My implementation uses a class I called WeakAction, which looks like this:

weakaction

The collection used by Mediator, which maps a Message to a list of Action<object>, is called MessageToActionsMap.  That class uses the WeakAction type, as seen below:

message2actions

As you can see in the following Mediator method, this implementation detail does not bubble up into the public-facing API:

mediator

You can download the prototype source code and demo app here: Mediator Prototype and Demo .  NOTE: Be sure to change the file extension from .DOC to .ZIP, and then decompress it.

If you have any suggested improvements, bugs, etc. please don’t hesitate to let me know.


Article about UX design for multi-touch systems

April 6, 2009

An article by Joel Eden, a colleague of mine at Infragistics, was recently published in Dr. Dobb’s. The article is called ‘Designing for Multi-Touch, Multi-User and Gesture-Based Systems‘.   It touches on the very interesting topic of how to design good user experiences for the next generation of multi-touch systems, such as Microsoft Surface applications.  This is something that I have been wondering about, so I was thrilled to discover this article.  It is very well written and explains the subject matter in a clear, understandable way.  For example, here’s an excerpt that I find very thought provoking…

If gestures are already so much a part of our cognitive processing then in some ways, the growing excitement around gesture-based systems is a sign that software systems are finally catching up to how we already think and behave, rather than really representing an innovative way of interacting with information.

You can read the article here: http://www.ddj.com/architect/216402697


Real World WPF Training for Free

April 2, 2009

Jaime Rodriguez and Karl Shifflett recently announced that they will be traveling the world to teach how to use WPF to create Line of Business applications…for free!  Those guys really know WPF and what it takes to build business apps, so I’m sure their training sessions will be packed with useful, important, interesting information.  You can read more about this exciting opportunity on Jaime’s blog:

Announcing the “WPF for LOB” Training Tour

Considering that their previous training sessions were sold out, if you are interested in attending, I highly suggest you register asap.


I am a Microsoft MVP again!

April 1, 2009

Great news arrived today.  Microsoft has given me the MVP title, once again!   This my third year in a row as an MVP, and hopefully not my last.

I must say, though, that receiving this notification on April Fool’s Day is slightly unnerving:D


Follow

Get every new post delivered to your Inbox.

Join 284 other followers