MVVM Pattern

I am trying to present what I learnt today on MVVM pattern with an example and comparative study on legacy code and MVVM Code. It goes with an assumption that readers has experience with WPF.

This design pattern is used for WPF /Silverlight kind of application.

To start with, we all know MVC(Model-View-Controller), MVP(Model-View-Presenter) . Now it is Model- View-View-Model. Though the purpose of defining all these patterns is to separate visual representation from business Logic.  We have to choose between these patterns based on the Technology we use.  To be more specific, below table represents the usage part:

UI Technology

MVP

MVC

MVVM

WPF

Can Use

Cannot Use

Best

Silverlight

Can Use

Cannot Use

Best

MVC Web

Can Use

Best

Can Use

Old Windows forms

Best

Cannot Use

Can Use

Old Web

Best

Can Use

Can Use

From Above:

Can use: Can create application in that technology using these patterns

Best: Suits more than ‘can use’

As WPF supports Bindings, Commands and Data Templates, MVVM best suits to this technology.

Model – Contains collection of classes which represents business data from the Data access layer or Database

View – View provides visual representation of the data that is been passed from Model.

ViewModel – This acts as a connector between Model and View.

We will now look at an example to understand more on how we can implement MVVM pattern in our applications.

Scenario: You need to develop an application which will show color coding for available stock. Your UI should have 2 buttons, Textbox and a label. Textbox should show the available stock, label should show the color coding. Two buttons should read as Increment and Decrement and perform stock increment or stock decrement actions.

Stock Count Label Background color Label text
>15 Over stocked Red
>10 Normal Stocked Blue
>5 Optimal stocked Green
Else Under stock Aqua

Solution:

In General if we develop this in normal ASP.Net web application, we get the stock count from Business layer to the UI and check the count. Based on the count you define the color coding as defined in the requirement. By doing so you are tightly coupling UI and the logic.  So you will end-up writing lots of code in Codebehind file of the view.

Using MVVM pattern, we can easily move this code in to a ViewModel class and de-couple view and the logic.

Create three different projects as shown below.

  • Create a class library and name it as Model.
  •       Rename the existing class as StockModel.cs.
  • Create another class library and name it as ViewModel
  •       Rename the existing class as StockView.cs
  • Create WPF application and name it as WPFStock

Project

Open Stock Model class and define a property and two methods to increment and decrement StockCount. Make sure you handle exception in Decrement method when stockcount goes <=0;

Now open expand ViewModel project and open StockView.cs and copy paste below code into it.

namespace Model{public class StockModel{private int _stockCount = 0;

public int StockCount

{

get { return _stockCount; }

set {_stockCount = value; }

}

public void IncrementStock()

{

StockCount++;

}

public void DecrementStock()

{

if (StockCount <= 0)

throw new Exception(“Operation   Not Allowed”);

else

StockCount–;

}

}

}

Below StockView class implements INotifypropertyChanged. This is because, we moved the logic form View codebehind to a saperate class called stockView.

INotifyPropertyChanged interface is available in System.Component Model name space, so this need to be imported into the solution. This is used to notify the view as and when any property gets changed.

As said earlier, ViewModel acts as the connector between View and the Model, we need to define properties and Methods which can bind to the controls on the UI.

We have a label, textbox and two Buttons on the view, so we need to create two properties to bind label color and content respectively.  Another property to display stock count in the textbox. Two methods to respond to button click events.

When we separate View and Model, we even need to capture button click events in ViewModel. To do so we need to utilize commands feature in WPF. These are derived from ICommand interface with two methods CanExecute and Execute. If you look at below code we declared Icommand instance and passed  Actions (also called as readymade delegates) with pointer to the target function.

Now to allow these binding, we declare Propertychanged delegate and define refresh method as shown in the below code. This method will notify changes in the property values to the view and allow user to see the latest value.

namespace ViewModel{public class StockView:INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;

private StockModel objStock = new StockModel();

private btnClick ocommand;

public StockView()

{

ocommand = new btnClick(new Action(btnIncrement), new Action(btnDecrement));

}

public ICommand btnClick

{

get { return ocommand; }

}

public string TxtStock

{

get { return objStock.StockCount.ToString(); }

set {objStock.StockCount = Convert.ToInt32(value); }

}

public string lblColor

{

get

{

if   (objStock.StockCount > 15)

{

return “Red”;

}

else if   (objStock.StockCount > 10)

{

return “Blue”;

}

else if   (objStock.StockCount > 5)

{

return “Green”;

}

else

return “Aqua”;

}

}

public string lblValue

{

get

{

if   (objStock.StockCount > 15)

{

return “Over   Stocked”;

}

else if   (objStock.StockCount > 10)

{

return “Normal   Stocked”;

}

else if   (objStock.StockCount > 5)

{

return “Optimal   Stocked”;

}

else

return “Under   Stock”;

}

}

public void Refresh(string propertyName)

{

if (PropertyChanged != null)

{

PropertyChanged(this,new PropertyChangedEventArgs(propertyName));

}

}

public void btnDecrement()

{

try

{

objStock.DecrementStock();

Refresh(“TxtStock”);

Refresh(“lblValue”);

Refresh(“lblColor”);

}

catch (Exception ex)

{

throw ex;

}

}

public void btnIncrement()

{

objStock.IncrementStock();

Refresh(“TxtStock”);

Refresh(“lblValue”);

Refresh(“lblColor”);

}

}

btnClass definition: In this class we define a constructor with multiple Actions or an Action collection. Based on the command parameter we invoke respective methods.

public class btnClick : ICommand{public bool CanExecute(object parameter){return true;

}

public event EventHandler CanExecuteChanged;

private Action IncrementExecute;

private Action DecrementExecute;

public btnClick(Action exec1, Action exec2)

{

IncrementExecute = exec1;

DecrementExecute = exec2;

}

public void Execute(object parameter)

{

if (parameter.ToString().Equals(“Increment”))

{

IncrementExecute.Invoke();

}

else

{

DecrementExecute.Invoke();

}

}

}

Now that you are done with Model and View Mode, its time to define View. To do this we need to define a namespace for the newly created ViewModel in the MainPage.xaml as shown below

xmlns:vm=”clr-namespace:ViewModel;assembly=ViewModel”

then create Resources

<Window.Resources>

<vm:StockView x:Key=”vmObj”/>

</Window.Resources>

Once namespace and resources are defined, we need to create binding using properties for each control.

properties

As a sample I have shown here how to configure binding for a control.

To conclude, Using MVVM pattern, we completely avoided code behind for the View. We were able to define all methods in View Model and Logic in to Model classes.

Now our View is independent of the logic which enables us to add new Views and define their control in the View Model  classes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s