Adding transitions to a MVVM based dialog

In my last blog post about MVVM, I showed how it is natural to build a common WPF dialog using DataBinding and Templates with the Model-View-ViewModel methodology. Because I’m having a lot of feedback on posts I wrote about how transitions can be done in WPF, I decided to reuse my previous demo application and add transitions when switching from one element to another. Here is the result of the demo application:

Get the Flash Player to see this content.

I didn’t wanted to implement all the transitions, instead I decided to use the famous FluidKit library and to wrap its transition control into a reusable and “MVVM compliant” control. I thank Pavan Podila for giving me feedback while designing this control.

Basically, based on Pavan suggestions I created an INavigationAware interface and subclass transitions I wanted to reuse from FluidKit. The INavigationAware interface allows me to specify that the transition supports going forward and going backward (regarding the previous and current selection of the user in the menu).

The control itself (that I call a NavigationPresenter) is very simple, I just use 2 ContentPresenter that I switch when the Content property changes using the TransitionPresenter control from the FluidKit library. The NavigationPresenter works with 3 dependency properties:

  • GoForward (bool): to specifiy the way of the transition
  • Transition: to specify the transition to use
  • Content: to specify the content of the control

Here is the XAML for using the NavigationPresenter

1
2
3
4
5
6
7
8
9
<!-- The ContentProperty is not bound directly to the SelectedItem of the ListBox because the
     GoForward property must be updated BEFORE the content changes. The CurrentContent property
     is defined in the ViewModel class and updated everytime the selection of the ListBox changes,
     after setting up the GoForward value. -->
<NavigationTransition:NavigationPresenter 
    Content="{Binding CurrentContent}"
    Transition="{Binding ElementName=transitionComboBox, Path=SelectedItem.Tag}"
    GoForward="{Binding DataContext.GoForward, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type AnimatedContentPresenter:MainDialog}}}">            
</NavigationTransition:NavigationPresenter>

The sample application comes with 3 animations but more can be used from the FluidKit library. It’s also possible to create your own transition (inherit from Transition base class). You can download the sample application here. Hope you’ll like it !

27 thoughts on “Adding transitions to a MVVM based dialog

  1. Hi Jeremy,

    I was looking for a viewmodel for the fluidkit and I found this article on your blog.

    I checked it out and it looks great!

    There’s only one small problem I have with it. When I add for instance a textbox to one of your controls I can’t edit the textbox. Is it because you use a contentpresenter or am I missing something? What would I have to do if I want to switch between editable controls?

    Can you please help me!

    Best Regards,
    Robert

  2. I wrote an override of the VisualChildrenCount property. Because I override GetVisualChild (because I’m using my own UIElementCollection) the VisualChildrenCount must be overriden too so that the visual tree will be enumerated properly. However, maybe all that would also work using a ContentControl…

  3. Hi Jeremy,

    Sorry to bother you again but I noticed another strange behaviour!

    The 4 pageviews you’ve created are closed and created each time you do a transition. When you for instance add a breakpoint in the Page1View constructor you see the control gets created each time you do a transition from or to Page1View.

    I didn’t notice this behaviour when I used the FluidKit without your ViewModel.

    Regards,
    Robert

  4. Hi All,

    Can anyone tell me how to refer controls which are in UI in View from ViewModel classes in MVVM Design Pattern for WPF.

    Like if i have an WPF interface in View and want to write events in ViewModel, this i know how to do. But, when i need to refer the controls for example validation or etc. as we were earlier doing like “this.txtFirstName” in VS2.0, how can this be achievable in ViewModel class.

  5. Hi Shashi,

    Actually, you’re not supposed to refer view related stuff (like controls) in the viewmodel classes. The viewmodel represents an abstraction of the view: one of the advantage of this is that you can unit test your viewmodel classes easily.

    There are 2 ways controls can “talk” with viewmodel classes: through databinding and through command. Using databinding you can ensure that viewmodel properties and view controls are in sync. Using commands, you can react to a user interaction in your view (for example a click on a button – without using events). If you need to deal with ItemsControl (ListBox for example), you can use ICollectionView too.

  6. quote:”I didn’t notice this behaviour when I used the FluidKit without your ViewModel.”

    But I noticed this behaviour with Transitionals framework. Without using a transition between usercontrol the visual state is lost. With Transitionals I switch/fade between datatemplates and the entered data in a textbox is saved switching back… ???

    Someone knows why?

  7. I think it depends whether the transitionals framework you use re-create the control each time. In this simple example it’s the case.

  8. Hello Jeremy,

    I checked your sample again and the Visual State of the GUI is lost changing the pages. According to this statement I am interested in an answer:

    Jeremy Says:
    April 9th, 2009 at 10:31 am
    Hmmm I noticed this behaviour too. I’ll check it out as soon as I can to try to understand how to fix it…

    Do you know now how to fix with your code the visual recreation ?

  9. Hello Jérémy,

    Comme évoqué précédemment, j’utilise actuellement ta classe “NavigationPresenter” pour réaliser des transitions entre view. Je suis parti pour cela du code fourni dans ta solution AnimatedContentPresenter.sln.

    Tout fonctionne bien…

    Sauf que quand je place un “breakpoint” sur le constructeur de Page1View, je m’aperçois que la vue est instanciée 2 fois au lancement de l’application… J’ai pas réussi à comprendre pourquoi . De même, lorsque que j’active l’animation de la “Page2″ (pour passer de la Page1 à la Page2), je m’aperçois que le constructeur de cette View est appelé 2 fois de suite; et que celui de la page1 est également appelé une fois …

    De ton côté, tu as déjà constaté ce mode de fonctionnement bizarroïde ?

    Fred

  10. Hi Jeremy!

    Great article and code. Using your code I found an interesting situation (this is probably something obvious, but can’t figure it out being somewhat new to WPF). I have the following XAML (inside main window):

    The data context is set to a ViewModel that implements CurrentContent property which has the correct ViewModel assigned to based on the user’s choice and GoForward bool property. But WPF expects me to implement GoForward property on the object that’s assigned to CurrentContent – I get a warning in console that the object doesn’t have this property (which is correct as the property is implemented for data context assigned to main form).

    Is this intended behavior or am I missing something?

    Thanks, Tom

  11. Hm, seems like the code wasn’t accepted above, here it is again without :

    <navigator:NavigationPresenter Content=”{Binding CurrentContent}” GoForward=”{Binding GoForward}” />

    Hope it works this time…

  12. I really like this demo. I’m trying to do the same thing but want to use buttons instead. I’m having a hard time trying to figure out where to put the “COMMAND” so the pages will flip. I’m new to MVVM and WPF. Any help would be appreacited?

  13. Vincent,

    I think you could use databinding with the help of a converter to databind the Content property to the current view. Then a simple command whould change the property databound to the Content property (in the ViewModel layer)… Or am I missing something ?

  14. Tomaz,

    What about using RelativeSource to “go up” and get the parent DataContext (this is something commonly done in WPF…)

  15. Hi Jeremy,

    Could you give an example? I have the button in the Panel.

    first, can you explain how the listbox gets the event and makes the content property change?

    Second, would it be possible you could show what you mean in your response to me?

    Sorry to be a pain I’m new to WPF but getting the hang of it. Your demo is really helpful.

  16. Hey Jeremy,

    many thanks for this great example! That is almost what I need for my application. Before I start to go deep in the code I wanted to know your opinion: I need to change the pages by using mouse or touch gestures (not by buttons like in your example). That means I want to grab a page on any spot and move it away… similar to the control an smartpones nowadays. including ineria and so on.

    Do you think I can use your example as basic for my intention?

  17. Hi…how can iset istabstop for <NavigationTransition:NavigationPresenter ?
    i want that NavigationPresenter cant get Tab Focus

  18. Hi jeremy.
    In your Sample i need that the NavigationPresenter in mainpage dont get tab focus…i set KeyBoardNavigation.IsTabStop=”False” But it dosent work!!!!!

  19. Azad,

    I’m not sure what is causing this issue. I know that focus in general can be a little tricky with WPF… Let us know if you find out the issue !

  20. Hi guys I know this blog is old but maybe someone is able to help me.

    I have created a NavigationPresenter, set the Transition to Cube, GoForward true and the content property to my CurrentView object.

    When I start my application only my shellView shows up.

    I’m using the Wpf Application Framework, FluidKit and the NavigationPresenter

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>