Click here to Skip to main content
Click here to Skip to main content

MVVM - Demo

, 6 Aug 2012
Rate this:
Please Sign up or sign in to vote.
If you are new to MVVM this is the place to start. Explains MVVM through an example.

MVVM

The model-view-viewmodel is a typically WPF pattern. It consists of a view that gets all the user input and forwards it to the viewmodel, typically by using commands. The view actively pulls the data from the viewmodel by using data binding. The model doesn’t know about the ViewModel and the ViewModel doesn’t know about the View. 

Explaining MVVM through an example

Let’s create a sample Patient Management Application using MVVM. Going step by step we must first define our Model, then define the ViewModel and finally the View.

Step 1 - Creating the Model:

Def: The Model is often referred to as Domain Model, completely UI independent that stores the state and helps in the processing of the problem domain.

In our example Model becomes the DOM object which is nothing but the patient entity. The sample below shows the patient Entity.

public class Patient
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Int64 MobileNumber { get; set; }
}   

Step 2 – Creating the View Model

Def : The term means “Model of a View”, and can be thought of as abstraction of the view, but it also provides a specialization of the Model that the View can use for data-binding. In this latter role the ViewModel contains data-transformers that convert Model types into View types, and it contains Commands the View can use to interact with the Model. The ViewModel has been likened to a conceptual state of the data as opposed to the real state of the data in the Model. 

Coming back to our example lets create the PatientViewModel which will expose the Properties(which contains the Data) and Commands (User actions) which will be binded to the view. 

Public  Properties : 

All the data that needs to be binded to the View will be exposed as public properties. The View Model will implement PropertyChanged Event so that the view will be updated automatically whenever there is a change in the ViewModel. To do this we are triggering the PropertyChanged event when the property is set.

public class PatientDetailViewModel: INotifyPropertyChanged
{
//    ...
    public int Id
    {
        get { return domObject.Id; }
        set
        {
       domObject.Id = value;
       OnPropertyChanged("Id");
        }
    }
//    ...
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
           PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
} 

Commands :
Def : The main idea is to move the whole presentation logic to the view model. This can be attained by using another feature of WPF, namely Commands. Commands can be bound like data and are supported by many elements as buttons, toggle buttons, menu items, checkboxes and input bindings. The goal here is not to have any line of logic in the code-behind of a view.

The View will execute commands on user action and the commands will be implemented in the ViewModel. To do this, you can’t use the standard WPF RoutedUIEvent, but you can easily develop your own command classes. A common way to do this is to create a command object that calls a delegate you specify.
Here is an example of how you can define a custom command class which you will later use when you are defining the commands in the ViewModel.

public class RelayCommand : ICommand
{
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    public RelayCommand(Action<object> execute)
        : this(execute, null){}

    public RelayCommand(Action<object> execute,
Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

Coming back to our example, our sample app requires Add, Delete & Search functionalities. The sample shows how to implement Add command using the RelayCommand that we defined above.

public class PatientDetailViewModel: INotifyPropertyChanged
{
    public ICommand AddPatientCmd { get { return _addPatientCmd; } }
    public PatientDetailViewModel()
    {
        _addPatientCmd = new RelayCommand(Add, CanAdd);
    }

    public bool CanAdd(object obj)     {  //Logic   }
    public void Add(object obj)  {  //Logic   }
} 

Step 3 – Creating the View

Def : A View is defined in XAML and should not have any logic in the code-behind. It binds to the view-model by only using data binding. The view involves mostly just setting up the UI and bindings to the ViewModel. The DataContext property for this control will be set to the ViewModel.

As we have created the PatientViewModel all we need to do is create the PatientDetailView and then bind the ViewModel as the DataContext. The Sample here shows Property binding and Command binding.

<UserControl ...>
    <!--Bind the View Model to the View. -->
    <UserControl.DataContext>
       <ViewModels:PatientDetailViewModel/>
    </UserControl.DataContext>
    ....
    <TextBox Name="TbxName" .... 
         Text="{Binding Path=Name}"/>    
    ....
    <Button Name="BtnAdd" Content="Add" ....
        Command="{Binding AddPatientCmd}"/>   
.....             
</UserControl>

Points to Note 

Since in a real life project you usually have more than one data object per view, using a view model becomes convenient since you can aggregate all data objects into one single View Model that exposes the aggregated data as properties and that can be bound to the DataContext.

The key point to MVVM is to make the view completely concerned with how data looks, never about behavior. Ideally, a view should be completely plug-and-play, with the only work being to hook up the bindings to the ViewModel.

In addition, separating all the behavior from the GUI allows you to be far more complete in unit testing.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ravi Teja Pidaparthi
Software Developer Wipro Technologies
India India
No Biography provided

Comments and Discussions

 
QuestionAbout Model & Model View PinmemberJohnSlagle30-Jul-13 5:31 
Would it be possible for the ViewModel to inherit from Model? I am just looking at the duplication between the two.
AnswerRe: About Model & Model View Pinprofessional_Maxxx_29-Oct-13 18:11 
GeneralMy vote of 5 Pinmemberusrikanthvarma13-Jul-13 13:40 
GeneralMy vote of 2 Pinmembercocowalla7-Jun-13 3:31 
QuestionVS 2010 Issue PinmemberNapalm68430-Jan-13 3:26 
GeneralMy vote of 5 Pinmembersairajk18-Jan-13 3:14 
GeneralMy vote of 5 Pinmembersaurabh kumar seth9-Jan-13 6:52 
GeneralMy vote of 3 Pinmemberprashant patil 498721-Aug-12 0:40 
QuestionMVVM Explanation Pinmemberprashant patil 498721-Aug-12 0:37 
AnswerRe: MVVM Explanation PinmemberMember 29202396-Dec-13 20:12 
QuestionMy vote of 4 PinmemberCandyJoin9-Aug-12 3:21 
GeneralNice article. Pinmembersagar13107-Aug-12 2:11 
GeneralMy vote of 3 PinmemberKlaus Luedenscheidt6-Aug-12 18:50 
GeneralRe: My vote of 3 PinmemberRavi Teja Pidaparthi7-Aug-12 1:36 
QuestionThe problem with MVVM Pinmemberkaschimer6-Aug-12 9:08 
AnswerRe: The problem with MVVM PinmemberRavi Teja Pidaparthi6-Aug-12 9:37 
AnswerRe: The problem with MVVM Pinmembercjb1106-Aug-12 22:22 
GeneralRe: The problem with MVVM PinmemberRavi Teja Pidaparthi7-Aug-12 1:32 
GeneralRe: The problem with MVVM PinmemberHarsh Baid20-Aug-12 1:09 
GeneralMy vote of 4 PinmemberChristian Amado6-Aug-12 8:21 
GeneralRe: My vote of 4 PinmemberRavi Teja Pidaparthi6-Aug-12 9:39 
QuestionYou already posted this as a blog PinprotectorPete O'Hanlon6-Aug-12 6:38 
AnswerRe: You already posted this as a blog PinmemberRavi Teja Pidaparthi6-Aug-12 9:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140709.1 | Last Updated 6 Aug 2012
Article Copyright 2012 by Ravi Teja Pidaparthi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid