views:

527

answers:

5

I have the following question regarding MVVM light: what "drives" the UI? I see I can have a ViewModel per View I am showing; the ViewLocator handles all the ViewModels (for caching as I understand). But what is driving the UI?

If I have a Command defined in my ViewModel that says "ShowDetail"; do I have to write the code for displaying this View inside the ViewModel?

Are there any examples of this? Thanks!

+1  A: 

In MVVM, what "drives" the view is data binding. You can connect the View to the ViewModel by setting the View's DataContext to point to the view model.

Simple example (using MVVM Light):

MyViewModel.cs

public class MyViewModel : ViewModelBase
{
   (...)
   private string _myProperty;
   public string MyProperty {
       get { return _myProperty; }
       set {
           _myProperty = value;
           RaisePropertyChanged("MyProperty");
       }
   }
}

MyView.xaml.cs

void MyView() {
   DataContext = new MyViewModel();
}

MyView.xaml

<TextBlock Text="{Binding MyProperty}" />
robertos
My questions was more related to loading different views. I understand the binding mechanism with a ViewModel. But where do I write code to show a new View when the user executes for example the "Show Details" button?
Stefan de Vogelaere
+4  A: 

The MVVM pattern by itself doesn't have anything specific for navigation between views. Although, there are many solutions for that in several frameworks. The most common solution is to use some sort of controller that "orchestrates" the main View, or to use a "Master-Detail" approach for subviews.

Some interesting solutions:

robertos
+1  A: 

I have created a T4 template that generates code and shows how to navigate to a uri or object, or close a window (wpf). It works with mvvm light

Download here

Rick Ratayczak
A: 

Hi Stefan,

I think you could check out Cinch V2 (http://www.codeproject.com/KB/WPF/CinchV2_1.aspx) which seems quiet promising. However I think most of these frameworks are fairly difficult.

I implemented a solution with a simple MVVM approach with some kind of supervising controller pattern which handles communication between Views and View-Models.

Kind regards, Kurt. ([email protected])

Kurt De Kempeneer
A: 

I would recommend that you read-up on the Messaging system in the MVVM light toolkit. This seems to be the simplest approach I have found to accomplishing this. Here is an example of how it works:

If you have 2 view models - 1 for searching customers, the other for display details about the selected customer:

In first view model, you have a property such as this:

public string CustomerID
    {
        get
        {
            return _customerid;
        }

        set
        {
            if (_efolderid == value)
            {
                return;
            }

            var oldValue = _customerid;
            _customerid = value;

            // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
            RaisePropertyChanged("CustomerID", oldValue, value, true);
        }
    }

Then, in the second view model, you register to recieve messages when this value changes from the other, such as this:

    void registerForMessages()
    {
        Messenger.Default.Register<PropertyChangedMessage<string>>(this,
            (pcm) =>
            {
                if (pcm.PropertyName == "CustomerID")
                {
                    customerID = pcm.NewValue;
                    AddWorkplanCommand.RaiseCanExecuteChanged();
                    loadCustomerDetails();
                }
            });
    }

Be sure to call your registerForMessages() function in the constructor of the second view model. Another thing that helps is to create a map of sorts when you have 4 or more ViewModels in your application. I find is easy to construct one in a quick text file in the solution to keep track of all the messages and what they are intended to accomplish, and which other view models are registered to recieve them.

One of the really nice things about this is that you have have 1 viewmodel send a change notification, such as the customerID property changed, and immediately have 4 other viewmodels recieve that change and all start loading changes themselves.

Ryan from Denver