Appendix B. Model-View-ViewModel (MVVM)

What is Model-View-ViewModel (MVVM)? MVVM is one of the design patterns that help developers define a clear separation between the user interface and application logic. Having this clear separation helps improve the testability of applications and allows developers and UI designers to work together on the application. This pattern is a variation of the Model-View-Controller (MVC) and Model-View-Presenter (MVP) patterns. MVVM got a lot of attention in the WPF and Silverlight world a few years ago because it works best with the core features of WPF/Silverlight, such as data binding, XAML markup extension, and so on. It’s now widely adapted in other development platforms. We understand that you may not fully understand how this pattern improves the testability and developer/designer collaboration at this point. We’ll give you detailed explanations with examples later in this section.

First, let’s look at the main components of MVVM. MVVM consists of three main components: Model, View, and ViewModel.

B.1. The Model class

Responsibility—The Model is a class that encapsulates the business logic and data of your application. It has the responsibility of validating the business logic and managing the data flow. Say you’re developing a contacts-management application. The Model class for your application will be a class called Contact that has properties like First Name, Last Name, Phone Number, and so on. It should have some validation logic such as checking the required field and phone number format. You can also put the logic for saving new contacts and updating and retrieving the existing contacts in that model class.

Management—The model classes should be managed by developers.

Variation—Some developers want to keep separate classes for domain data structure and the data flow. It’s totally dependent on the developers’ preferences, but we recommend that if you have very thick logic in your model, it’s best to split it into small model classes.

B.2. The View class

Responsibility—The View is responsible for managing the appearance of your application. In XAML development, the View is usually a user control, data template, window, or page that contains the structure of UI elements you want to show your user, based on the requirements of the application.

Management—The View is created by UI designers (not developers), but they need to get the model contract from developers and create the mock while they’re designing the View, using tools like Expression Blend. Ideally, the View shouldn’t have any coding except the defaults, but there are scenarios where the UI logic you want is very difficult to achieve by using attached properties or binding. In those cases it’s OK to have the UI logic in a code-behind file of the View.

Variation—None.

B.3. The ViewModel class

Responsibility—The responsibility of the ViewModel is to handle all presentation logic required for the View. The presentation logic includes the validation of inputs entered by the user in the ViewModel. It has the responsibility of coordinating between the View and the Model. We’ll talk about how the Model, View, and ViewModel interact with each other later in this appendix.

Management—The developer implements all required logic in ViewModel and handles the interaction between the View and the Model.

Variation—You may or may not want to have a View reference in the ViewModel. Some developers believe that the View and ViewModel should communicate via binding, but others say that having a weak/strong reference of the View in the ViewModel makes things a lot easier. In our opinion, we don’t think there’s anything wrong with either approach, but having a reference of the View in the ViewModel is like using MVVM and MVP together.

Now that you know what the Model, View, and ViewModel are, let’s see how these components communicate with each other.

B.4. Interaction between the Model, View, and ViewModel

The interaction between each component is shown in figure B.1. The View and ViewModel communicate via data binding, and the ViewModel talks to the Model, but there’s no direct communication between the View and the Model.

Figure B.1. The interactions between the View, Model, and ViewModel

Let’s talk more about the details and responsibilities of each component and their interactions, using a very simple MVVM example. Create a new Windows Phone project called MvvmSample in Visual Studio 2012. To make the sample as simple as possible, you’re not going to use any database, service, or validation. It will be just an application that can show the list of contacts and allow a user to add new contacts.

Note that we’re assuming you’re already familiar with data binding, the ICommand interface, and the INotifyPropertyChanged interface. If not, you should read about them before starting to work on this example. If you have additional questions after reading about data binding, please post your questions to the Windows Phone 8 in Action Manning author forum at http://mng.bz/FiU4. Here are some other resources:

B.4.1. Adding the Model class

You’ll start by adding a new Model class called ContactModel to your project. Do you recall the responsibilities of the Model class? The Model encapsulates the structure of your business object and holds the business logic. Because this is just a sample to show how to use the MVVM pattern, you’re not going to add the validation or business logic inside, but remember that the Model is a class where you can put business logic when developing a real-life business application. You’ll implement the INotifyPropertyChanged interface because the Model is a very simple one, and you don’t need any presentation logic that requires an additional ViewModel, so you can simply bind the Model with the View via the ViewModel class. The ContactModel will be like that shown in the following snippet. We add only one property called Id to make the code short, but you should add three more properties such as FirstName, LastName, and PhoneNumber to the Model class. The data type of those three properties should be string. You can also download the full example from the source code that comes with this book. The implementation of ContactViewModel is as follows:

using System.ComponentModel;

public class ContactModel :  INotifyPropertyChanged
    {

        private int _id;
        public int Id
        {
            get { return _id; }
            set
            {
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

B.4.2. Adding the ViewModel class

You’re going to add a ViewModel called ContactViewModel to your project. The ViewModel needs to handle all logic related to the UI and communicates between the Model and the View. Because it’s a ViewModel, you need to implement the INotifyPropertyChanged interface, and you can use the same code you used in the Model class. You may be thinking, “Why do we need to duplicate the code?” If you were working on a real-life business application, you’d probably create an abstract base class and make that implementation as a common function. Also, do you see the magic string in the Id property? You’re using it because it’s just a sample project, but there are several ways to eliminate those magic strings by using lambda expressions or Aspect Oriented Programming (AOP). If you’d like to know more, enter the keywords “INotifyPropertyChanged implementation with lambda expression” or “AOP INotifyPropertyChanged implementation” into your favorite search engine.

Let’s discuss what you’re going to have in the ViewModel. The implementation for the ViewModel is totally dependent on the View, so we need to discuss how the View will look. You’ll display the list of existing contacts at the top and the entry form at the bottom of the View. The entry form will have a button that can add new contacts to the list. In the ViewModel class you’ll need three properties: Contacts, Contact, and SaveCommand:

using System.Collections.ObjectModel;
using System.Windows.Input;

    private ObservableCollection<ContactModel> _contacts;
        public ObservableCollection<ContactModel> Contacts
        {
            get { return _contacts; }
            set
            {
                _contacts = value;
                NotifyPropertyChanged("Contacts");
            }
        }
        private ContactModel _contact;
        public ContactModel Contact
        {
            get { return _contact; }
            set
            {
                _contact = value;
                NotifyPropertyChanged("Contact");
            }
        }
        public ICommand SaveContactCommand { get; private set; }

Because you’re not going to have any persistence layer for the project, put some mock data in the constructor of the ViewModel class. Initialize the Contacts property with a list of mock data. Then initialize the Contact property and SaveCommand. The ActionCommand that you see in the sample is a simple implementation of the ICommand interface. If you’re looking for a proper implementation of the ICommand interface, we recommend you use the DelegateCommand from the Prism framework, Relay-Command from MvvmLight, or any command implementation from other mature MVVM frameworks. The implementation of ContactViewModel is as follows:

public ContactViewModel()
       {
           Contacts = new ObservableCollection<ContactModel>
           {
               new ContactModel() { Id = 1, FirstName = "Tifa", LastName =
     "Lockhart", PhoneNumber = "91988872" },
               new ContactModel() { Id = 2, FirstName = "Aerith", LastName =
     "Gainsborough" , PhoneNumber = "87366790"},
               new ContactModel() { Id = 3, FirstName = "Cloud", LastName =
     "Strife" , PhoneNumber = "46738633"},
               new ContactModel() { Id = 4, FirstName = "Aki", LastName =
     "Ross" , PhoneNumber = "776463839"},
           };
           Contact = new ContactModel();
         SaveContactCommand = new ActionCommand(() =>
         {
               Contacts.Add(new ContactModel() { Id = Contacts.Count() + 1,
     FirstName = Contact.FirstName, LastName = Contact.LastName, PhoneNumber
     = Contact.PhoneNumber });
               Contact = new ContactModel();
           });
       }

B.4.3. Adding the View class

You’ve now added one Model class and one ViewModel class to the project. Next you’ll add a View called ContactView. As mentioned, the View can be a data template, user control, window, or page. You’ll choose a user control as the View in this sample. You’ll show the list of contacts at the top, so you can add the ListBox control, LongListSelector control, or an itemcontrol to the View. Add the entry form where users will enter new contact information. To avoid lengthy code, you’re not going to add the whole XAML code here. You can refer to the View in the sample project for this appendix, which you can download with the source code for this book.

Add the ContentControl where you want to display the View in MainPage.xaml. You’ll bind the ViewModel and View in the next snippet in the code-behind of MainPage. You can display the View by setting the View to the Content of ContentControl:

var view = new ContactView();
view.DataContext = new ContactViewModel();
ContentControl.Content = view;
Note

You may not control the logic for showing the View from MainPage in a real-life project. You should create a controller (for example, a Navigation controller) to handle that navigation logic.

When you run the sample, you should see a screen like that shown in figure B.2.

Figure B.2. View of the MVVM sample

That’s all. You’ve successfully created your very first MVVM Windows Phone application. As you can see, the MVVM pattern is totally dependent on data binding, XAML markup extension, behavior, attached property, and the command pattern, so you need to master those things before learning about the MVVM pattern.

B.5. Patterns as solutions to common problems

Patterns were created to solve problems. Did you notice which problem you could solve by using the MVVM pattern? When you were working on the sample, you may have noticed that you didn’t need to write any code in the View. In the View, data binding and XAML cover everything. That’s why the View can be managed by the designers who are familiar with XAML and expression blend. In typical application development, developer and designer collaboration can be difficult. The designers used to create the application UI design with Photoshop or other graphics tools. Then they would send those images to developers. But the developers always had problems creating the actual UI based on the images they received from the designers. That’s why Microsoft came up with the idea for developers and designers to work together, so both parties are more productive and can produce better output.

We also mentioned that the MVVM pattern improves the testability of the application. If you’re coming from a Web Form or WinForm background, you already know how difficult it is to write the unit test for UI logic. But with the MVVM pattern, all presentation logic is separated from the UI, so you can easily write the unit test or practice Test-Driven-Development (TDD) in your development.

B.6. Summary

In this appendix, you’ve learned about the MVVM pattern, but you can’t use one pattern to do everything in real-life application development. You need to know a few patterns that work well with the MVVM pattern:

  • Event Aggregator pattern/Mediator pattern —You know how to communicate between View, ViewModel, and Model. What about communicating between ViewModel and ViewModel? What if you wanted to link from one View to another? This is where the Event Aggregator or Mediator pattern comes in. The pattern sits between Views and ViewModels to communicate with each other using push.
  • Dependency injection/Ioc —These patterns help manage object creating and the object lifetime. You can refer to a mature dependency injection framework, such as Unity (from Microsoft) or Autofac. If you’re looking for a book about dependency injection, we recommend Dependency Injection in .NET by Mark Seemann (Manning Publications, 2001) and Dependency Injection by Dhanji R. Prasanna (Manning Publications, 2009). Links to those books are at www.manning.com/seemann/ and www.manning.com/prasanna/.
  • Repository pattern —You can use this pattern to have one abstraction layer between your application logic and a persistence layer.

Those are the most common patterns developers use in applications that are heavily based on the MVVM pattern. We understand that MVVM is a big topic and you won’t fully understand it in one example. Practice with a few more examples and feel free to ask any questions in our forum at http://mng.bz/FiU4.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.151.21