Click here to Skip to main content
15,867,488 members
Articles / Web Development / ASP.NET

MVVM Silverlight 4.0 Simplified

Rate me:
Please Sign up or sign in to vote.
4.35/5 (9 votes)
15 Nov 2010CPOL4 min read 53.1K   1.9K   27   13
Implementing the MVVM pattern in Silverlight 4.0

Introduction

The MVVM is a design pattern based on the MVC/MVP patterns which are both trying to solve a similar problem. The MVVM pattern aims to separate the tightly bound UI code consisting of rendering, control actions and data-binding code.

For the sake of learning, I've kept the code very simple. I've attached the code as progressive but complete bundles so you can choose how much you want to learn at a time.

Background

The MVVM pattern can initially be quite intimidating to someone like me who has spent the last eight years familiarizing myself with the page behind code model. But I quickly discovered that it need not be this way and by adapting to this shift in the code paradigm, we can really benefit in many ways. I'd like to give Prabhjot Bakshi due credit for his wonderful article on the same subject, Brian Pring who introduced me to Silverlight with his exciting demos and Stephen Olah who actively contributed to my learning experience. I hope my experience in learning this pattern can benefit someone else.

The MVVM Concept

The MVVM pattern consists of 3 parts:

  1. View
  2. ViewModel
  3. Model

The view is bound to the viewmodel and any change in the model will automatically be reflected in the view. The ViewModel will handle any changes to the model and receive the events triggered on the view. Yes it’s that simple!

MVVM.jpg

Part 1

Here, I would like to introduce the basic concepts of the MVVM pattern which help logically separate your UI code into the View, ViewModel and the Model.

View

The View consists of code that renders the Silverlight application UI, which would consist of your XAML code. Ideally in implementing the MVVM pattern in its true sense, we want to avoid any code behind. So what this means is we need to connect the View to the ViewModel in the XAML itself. You’ll need to pay extra attention to details in this section as this can save you many hours of debugging.

First, I register the ViewModel namespace in my UserControl attribute list.

XML
xmlns  :  local  ="clr-namespace:MVVMApp.ViewModel"     

In my view, I have an outer Grid which I connect to my ViewModel:

XML
<grid.datacontext>
            <local:contactviewmodel>
        </local:contactviewmodel></grid.datacontext> 

Then an inner Grid that I bind to an instance of my model:

XML
<Grid DataContext="{Binding Path=mycontact}">

And finally the binding of the properties to the actual control that renders my text/data.

XML
<textbox grid.row="0" text="{Binding Path=FirstName }">
            <textbox grid.row="1" text="{Binding Path=SecondName }">
</textbox></textbox>

ViewModel

This is the tricky part, think of the ViewModel as a specialized proxy that connects to the model and in terms of ASP.NET, think of this as your code behind where you would have handled event code and data-binding.

C#
public class ContactViewModel
    {
        public Contact mycontact { get; set; }

        public   ContactViewModel()
        {
            Contact cont = new Contact();
            cont.FirstName = "Ritesh";
            cont.SecondName = "Ramesh";
            mycontact = cont;
        }
    }

Model

Think of the model as the structure that will contain your data. The Model will not implement any functionality of any sorts. But in order to use the model in the MVVM pattern, we require the model to implement the INotifyPropertyChanged interface. The INotifyPropertyChanged interface is used to notify clients, typically binding clients that a property value has changed.

My model has two properties FirstName and SecondName and implements the INotifyPropertyChanged interface. The NotifyPropertyChanged method checks if the property is valid and notifies my view of the propertychange.

C#
public class Contact :  INotifyPropertyChanged
    {
        private string _FirstName;
        public string FirstName { 
            get { return _FirstName; } 
            set { _FirstName = value;
            NotifyPropertyChanged("FirstName");
            } 
        }

        private string _SecondName;
        public string SecondName { 
            get { return _SecondName; } 
            set { _SecondName = value;
            NotifyPropertyChanged("SecondName");
            } 
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

Part 2

Here, I would like to advance to the next stage of the MVVM pattern. That is implementing a command using a button control that will trigger the automated data binding of the View and Model within the ViewModel.

View

I have added the following button syntax to the existing XAML of the View.

XML
<Button Grid.Row="2"  Command="{Binding Path=DataContext.GetContact ,
   ElementName= LayoutRoot }" Content="View"
                   CommandParameter="{Binding Path=Phone}" />

ViewModel

This is where most of the changes have been implemented to handle the buttons execution.

In my ViewModel, I have introduced a GenericCommand class that implements the ICommand interface that exposes the CanExecute, Execute methods and an event CanExecuteChanged.

  • CanExecute - Here you can implement any verification code that needs to be checked before execution can be called. In my code, I have set it to always return true.
  • Execute - This is where you would implement any code that needs to be executed on the button click event.
  • CanExecuteChanged - Fires when changes occur that affect whether or not the command should execute.
C#
public    class  GenricCommand  :  ICommand  
 { 
ContactViewModel _vm; 
public GenricCommand( ContactViewModel  vm) 
           {  
               _vm = vm; 
           } 

           public bool  CanExecute(object parameter) 
           { 
return true ; 
           } 

         public   event   EventHandler 
CanExecuteChanged; 

            public   void  Execute( object 
parameter) 
          { 
              _vm.showContact( ); 
           } 
      } 

Further, I have modified my ViewModel class to include a method called GetContact that returns an object of my GenricCommand class.

C#
public ICommand GetContact
      {
          get { return new GenricCommand(this); }
     }

This in turn delegates the code to be executed when the button click is performed back to the showContact method which is contained in my ViewModel:

C#
public  void showContact()
      {
          mycontact.FirstName = "Ritesh";
          mycontact.SecondName = "Ramesh";
     }

Model

My model doesn’t require any changes.

Points of Interest

  • This is but one implementation of the MVVM pattern, there are many other ways to accomplish the same thing.
  • What the ViewModel should really consist of is still very much debatable, as an example, do I implement the sorting of a datagrid in the View itself or do I need to implement the functionality in the ViewModel is still a mystery to me?

References

License

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


Written By
Architect Infosolvex Solutions Inc
Australia Australia
Ritesh is an IT consultant with over ten years of experience in the IT industry varying from consultation, architecture, design, development to technical management. He has a strong background in solutions and applications architecture with a focus on Microsoft’s .Net platform. His area of expertise spans design and implementation of client/server, database and web-based systems. He has worked with C#, ASP.NET 1.1 and 2.0, ADO.NET, Web Services and SQL technology on several enterprise class projects.




Freedom is not worth having if it does not include the freedom to make mistakes.
Mahatma Gandhi

Comments and Discussions

 
QuestionDid not work MVVM Pin
Salam633116-May-13 4:06
professionalSalam633116-May-13 4:06 
QuestionGood Job Pin
HariPrasad katakam19-Nov-12 20:44
HariPrasad katakam19-Nov-12 20:44 
GeneralMy vote of 4 Pin
cooolguymca12-Aug-11 2:04
cooolguymca12-Aug-11 2:04 
Question[My vote of 2] Generic? I don't think so... Pin
mBonafe16-Nov-10 3:30
mBonafe16-Nov-10 3:30 
Your "generic" execution object has a very specific command in the execute method. So what's the use of the "generic" class? It's not generic at all. Seems to me that your that you are reaching around your back to scratch your elbow (i.e. it just doesn't make sense).
Sharzoe

"We don't see things as they are, we see them as we are." -- Anais Nin

AnswerRe: [My vote of 2] Generic? I don't think so... Pin
Ritesh Ramesh16-Nov-10 11:28
Ritesh Ramesh16-Nov-10 11:28 
Generalmy vote is 4 Pin
PavanPareta15-Nov-10 1:50
PavanPareta15-Nov-10 1:50 
GeneralRe: my vote is 4 Pin
Ritesh Ramesh15-Nov-10 9:53
Ritesh Ramesh15-Nov-10 9:53 
GeneralMy vote of 5 Pin
defwebserver12-Nov-10 2:29
defwebserver12-Nov-10 2:29 
GeneralRe: My vote of 5 Pin
Ritesh Ramesh12-Nov-10 11:06
Ritesh Ramesh12-Nov-10 11:06 
GeneralMy vote of 2 Pin
SledgeHammer0111-Nov-10 5:16
SledgeHammer0111-Nov-10 5:16 
GeneralRe: My vote of 2 Pin
Kevin Marois11-Nov-10 5:25
professionalKevin Marois11-Nov-10 5:25 
GeneralRe: My vote of 2 [modified] Pin
Ritesh Ramesh11-Nov-10 9:52
Ritesh Ramesh11-Nov-10 9:52 
GeneralRe: My vote of 2 Pin
Ritesh Ramesh11-Nov-10 16:10
Ritesh Ramesh11-Nov-10 16:10 

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

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