handling events and storyboards in a MVVM pattern

Topics: Prism v2 - Silverlight 2
Jun 11, 2009 at 3:57 PM

I'm a bit confused as how I should handle specific things in a MVVM pattern.

Say I have a button in my view which should trigger the start of a Storyboard, defined in my View.

I've injected my View in the ViewModel. From the View I dispatch a click event using Command.Click.

In the ViewModel I've done the following :

 public DelegateCommand<object> ExpandCriteria;

 public SourceListViewModel(ISourceManagerService sourceManagerService,
                               IEventAggregator aggregator,
                               ISourceListView view)
    {

      this.View = view;
      view.SetViewModel(this);

      ExpandCriteria =  new DelegateCommand<object>(OnExpandCriteria, null);
    }

    private void OnExpandCriteria(object obj)
    {
         trigger the storyboard begin here.    
    }

First, is this the correct way of doing things ?

Second, how do I access the storyboard ? i can't see it from the ViewModel. I've defined it as a local resource in the View.

Thanks

Jun 11, 2009 at 7:54 PM

Hi,

 

To access the view’s storyboard, you can expose it in the view’s interface like this:

public interface ISourceListView

    {

        Storyboard MyStoryBoard { get; }

        // rest of the interface here

    }

 

Then in your view, you can implement the property getter to return the storyboard:

   public Storyboard MyStoryBoard

        {

            get

            {

                return this.Resources["MyResource"] as Storyboard;

            }

        }

 

In the OnExpandCriteria method you should be able to begin the storyboard:

private void OnExpandCriteria(object obj)

    {

               this.View.MyStoryboard.Begin();

    }

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman

Jun 12, 2009 at 10:46 AM

Thanks Damian,

 

Yes, that helps. Actually I was wondering what would be the approach for the VisualStateManager as it works differently from the Storyboard.

At the moment in my View I have the following code :

private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
      if (isExpanded)
      {
        VisualStateManager.GoToState(this, "CollapsedState", true);
      }
      else
      {
        VisualStateManager.GoToState(this, "ExpandedState", true); 
      }
      isExpanded = !isExpanded;
    }

 

And I would like to move this to a MVVM approach. What is the best way for doing this using the EventAggregator ?

Jun 12, 2009 at 7:43 PM

Hi

 

The way I see it, you can implement the MVVM approach and still have that code in the View’s code behind. I believe there is no need to find a way to trigger the animation from the ViewModel since it is fully UI related (if you were developing in WPF you could achieve this from XAML using Triggers).

 

If you are required to place this code in the ViewModel, I would not use the Event Aggregator to communicate the View and Model. As the article explains: “The EventAggregator service is primarily a container for events that allow decoupling of publishers and subscribers so they can evolve independently.”. In the MVVM pattern, or any other presentation pattern, the View and its Presenter/Controller/ViewModel are coupled and have no reason to evolve independently. Exposing common .NET events in the view’s interface (if the Model has a reference to the view), and calling Model methods, if the view has a reference to the Model are probably a better approach and less of an overkill.

 

As I said before, this is my own opinion without knowing your application specifics.

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman