Passing Parameters in Behaviours

Jan 24, 2011 at 9:49 AM

I'm quite new to both WP7 and MVVM so I thought a good start would be to start reading Jesse Liberty's posts using MVVM Light and WP7.

In his most recent post he demonstrates passing parameters in behaviours to help build a master-detail application. Unfortunately his post stops at the point I needed most help on...

...in his post on selecting an item a RelayCommand is executed with the Customer as a parameter. He then just shows a simple message box to show some detail about the customer.

What I would be interested in seeing is how the parameter is passed to the DetailsViewModel, followed by navigation to the DetailsPage. 

My first attempt had me creating 2 messages (one for the navigation and one for the Customer(changed)) but this doesn't feel right :( 

Any comments would be appreciated...(the following code is my first attempt for you to laugh at)

       public MainViewModel()
        {
            DetailsPageCommand = new RelayCommand<Customer>((msg) => ShowCustomerDetails(msg));
        }

        private object ShowCustomerDetails(Customer msg)
        {

	    // 2 messages are thrown, one to go to the right page and the second to set the customer context
            Messenger.Default.Send<Customer>(msg);

           
            var pageMessage = new GoToPageMessage { PageName = "Details" };
            Messenger.Default.Send<GoToPageMessage>(pageMessage);

            return null;
        }

Coordinator
Jan 24, 2011 at 10:51 AM

Hi,

As usual there are multiple ways to solve this.

  1. Send one message only, but have two recipients for this message, one that sets the selected customer, and the other recipient that navigates to the page.
  2. Avoid messages altogether, and instead use a hierarchy of viewmodels, and a navigation service.
  3. Use a message to set the customer, and the navigation service to navigate

Number 2 is usually my favorite for the scenario you mention:

  • Have a property on the Main VM (of type Customer) named SelectedCustomer.
  • Have the RelayCommand (or even a simple binding) assign the selected customer to that property.
  • Set the DetailsPage's DataContext to {Binding Source={StaticResource Locator}, Path=Main.SelectedCustomer}
  • Use the navigation service to navigate to the DetailsPage.

I talk about navigation service in the context of Windows Phone 7 here: http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx

I hope it helps to get a better picture or the alternatives.

Cheers,

Laurent

 

 

 

Jan 24, 2011 at 11:39 AM

Laurent,

Thanks for your speedy response...I had considered using the same ViewModel for both the Details and Master as you suggest in your response:

  • Set the DetailsPage's DataContext to {Binding Source={StaticResource Locator}, Path=Main.SelectedCustomer}

    but I imagined (for some reason) that this breaks some of the rules of MVVM.

    Thanks

    Scott

  • Feb 9, 2011 at 3:37 PM

    Its not really breaking rules, its really more of a what works preference when it comes to mvvm, obviously there are purists but this isn't a thread for that..  Aside from that what he is basically doing is passing a parameter via the binding based on the viewmodel you wanted to pass (DetailsViewModel), only its populated with the proper information from the mainviewmodel which just happens to have a Property of the type you needed, your just playing the path game.

    Apr 22, 2012 at 12:35 PM
    Edited Apr 22, 2012 at 12:35 PM

    hi,

    I have been looking at the Jesse Liberty's posts not passing in parameters to the ViewModel seemed a strange, but searching the web has not shown me a good solution. The hierarchy of viewmodels creates a dependency between the ViewModels, I like the message service and I would prefer the navigation service to have the responsibilty to pass message to the ViewModel.

     

    Paul