About Me

reno, NV, United States
As of 2011, I have ten years experience in various technologies as C#, WPF, Java, J2EE, C++. For the past three years, I have been extensively working on various .net and java technologies including but not limited to WPF , C# , WCF and composite application guidance (Prism ).

Tuesday, April 14, 2009

Running animations in MVVM

We implement Composite application guidance (Prism v2) in our application. Recently we wanted to run animations when something changes in ViewModel. The Viewmodel changes should initiate storyboards or run functions on view.xaml code behind.

I implemented a class ViewModelChangeDispatcher which can be useful to run animations.
You can instantiate this lightweight class from xaml as



OnSourceChangedStartStoryboard="XXXStoryBoard" />

The above VMCD is bound to Source xxxAnimation, this when changed will automatically call the storyboard...

If you want to manage multiple animations using the same, u can handle that by this code







When source is changed the event handler RunAnimation is called.

Anyway here is how I implemented ViewModelChangeDispatcher.


public class ViewModelChangeDispatcher : FrameworkElement
{
#region Data

public static readonly DependencyProperty SourceProperty;
public static readonly DependencyProperty OnSourceChangedStartStoryboardProperty;

// The routed event
public static RoutedEvent SourceChangedEvent;

#endregion // Data

#region Static Constructor and static methods


static ViewModelChangeDispatcher()
{
SourceProperty = DependencyProperty.Register(
"Source",
typeof(String),
typeof(ViewModelChangeDispatcher),
new FrameworkPropertyMetadata(string.Empty,OnSourcePropertyChanged));



OnSourceChangedStartStoryboardProperty = DependencyProperty.Register(
"OnSourceChangedStartStoryboard",
typeof(Storyboard),
typeof(ViewModelChangeDispatcher));


//Registering the events
SourceChangedEvent = EventManager.RegisterRoutedEvent("SourceChanged",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(ViewModelChangeDispatcher));

}

private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{

ViewModelChangeDispatcher vmcd = d as ViewModelChangeDispatcher;
if (vmcd == null) return;

vmcd.RaiseEvent(new RoutedEventArgs(SourceChangedEvent, vmcd));
if (vmcd.OnSourceChangedStartStoryboard == null) return;
vmcd.OnSourceChangedStartStoryboard.Begin();
}



#endregion

#region constructor and members
public ViewModelChangeDispatcher()
{
this.Visibility = Visibility.Collapsed;
this.Width = 0;
this.Height = 0;


}

/*
* Source is always string.
* It is the onus of the markupextension to convert it to a string.
*
* */
public String Source
{
get { return (String)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}



public event RoutedEventHandler SourceChanged
{
add { AddHandler(SourceChangedEvent, value); }
remove { RemoveHandler(SourceChangedEvent, value); }
}

public Storyboard OnSourceChangedStartStoryboard
{
get { return (Storyboard)GetValue(OnSourceChangedStartStoryboardProperty); }
set { SetValue(OnSourceChangedStartStoryboardProperty, value); }
}
#endregion


}




Please let me know if you have any comments/inputs!

Happy coding!
Pradeep Mahdevu

www.pradeepmahdevu.blogspot.com


Also refer Josh Twist's point of view on this.
joy of code
and pavan's post here...

Pixel in genie

10 comments:

SPoT said...

Also refer Josh Twist's point of view on this.
joy of code and pavan's post here...

Pixel in genie

abdul said...

Hi, This appears to be the solution I've been hoping for. But have been unable to make it work.
Can you provide a little more guidance on how to implement your solution please?
If you can be so kind as to give a small sample app.
Abdul

SPoT said...

Abdul, I can do that. Do you guys also implement prism? If so, i can write one implementing it else let me know

abdul said...

Thank you for the help. We are not implementing Prism. I was basically using MVVM framework based on Josh Smith's pattern.

Kind regards

SPoT said...

I spent some time and wrote this small code.. i hope you find it helpful. here is the linky... Also, let me know your thoughts.. http://pradeep.chandra.googlepages.com/MVVMAnimation.zip

SPoT said...

Also in the current implementation, i have created the view first and then created the model. hence, you see the animation running as soon as the app loads. we can change this by creating model first ( thats what we did in our project)...

abdul said...

Thank you for taking the time to code and post the demo.
It was very helpful. Your comment about creating the Model first though left me a bit confussed. As I would only want to run the animation from a Command on my viewmodel. I just cannot seem to that currently. Everytime I bind to the view to the viewmodel. The animation kicks off. Any help will be appreciated.

Thank you very much.
Abdul

Subbu"Think Big" said...

I'm trying to reproduce the steps in this post. but i'm not able to achieve. I'm getting an error:
'Storyboard' type does not have a public TypeConverter class.
And I'm not able to access googlepages site because of firewall. Can you please give me some more information.

Regrads,
Subbbu

SPoT said...

Hope this is helpful to you. I hosted it now on windows live...

http://cid-0bce839a43dc3b3e.skydrive.live.com/self.aspx/.Public/MVVMAnimation.zip

Subbu"Think Big" said...

That was very kind of you.
It was very helpful and I'm able to that solution. This was the solution i was looking for. In some solution I found they were calling Storyboard name from ViewModel which i found incorrect, as they will be using View related infromation in ViewModel.
Thanks for the help.

Cheers,
Subbu

Followers

Blogger Syntax Highliter