Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MVVM - Creating ViewModel: Wrap your business object (Solution 1 of n)

0.00/5 (No votes)
25 Feb 2010 2  
When you create WPF applications, you may (or you should !) use the M-V-VM pattern and so have to use/create ViewModel.The viewModel job is mainly to expose properties of your businessObjects to your views, ready for binding. Here is a first solution to create ViewModel from your model.

Introduction

When you create WPF applications, you may (or you should!) use the M-V-VM pattern and so have to use/create ViewModel. The viewModel job is mainly to expose properties of your businessObjects to your views, ready for binding.

To be ready for the binding, the most used solution is to implement INotifyPropertyChanged and to fire events for every change made. An issue is that you often do not create the business object used by the application which are created by another team and that these objects are not ready for binding. So you must find a solution to creates an object which will in fact be very similar of your business object, BUT ready for binding.

In this series of posts, I will try to give some of the solutions we can use to do so.

Wrap your Business Object (Solution 1 of n)

The first solution which appears in every developer's brain is to wrap theBusinessObject(BO) into the viewmodel. Every property of your ViewModel will actually be some kind of proxy to/from the underlying BO.

For example, let's take for granted that you have a businessObject like this:

C#
/// <summary>
/// I'm the business object created by another team. 
/// I'm not binding-aware : shame on me !
/// </summary>
public class MyBusinessObject
{
  public String LastName { get; set; }
  public String FirstName { get; set; }
  public int Age { get; set; }
  public List<String> FriendsName { get; set; }
}

You will then give the Business object to your viewModel which will act as a proxy. The result will be something like this:

C#
public class ViewModelWrapped : ViewModelBase
{
private MyBusinessObject _myBusinessObject;
private ObservableCollection<String> _friendsName;
 
public ViewModelWrapped(MyBusinessObject myBusinessObject)
{
  _myBusinessObject = myBusinessObject;
  _friendsName = new ObservableCollection<string>(myBusinessObject.FriendsName);
}
 
public String FirstName
{
  get { return _myBusinessObject.FirstName; }
  set
  {
    FirePropertyChanged("FirstName");
    _myBusinessObject.FirstName = value;
  }
}
 
public String LastName
{
  get { return _myBusinessObject.LastName; }
  set
  {
    FirePropertyChanged("LastName");
    _myBusinessObject.LastName = value;
  }
}
 
public int Age
{
  get { return _myBusinessObject.Age; }
  set
  {
    FirePropertyChanged("Age");
    _myBusinessObject.Age = value;
  }
}
 
public ObservableCollection<String> FriendsName
{
  get { return _friendsName; }
  set
  {
    if (value != null)
    {
      FirePropertyChanged("FriendsName");
      _myBusinessObject.FriendsName = value.ToList<String>();
    }
  }
}
}

Notes: Something interesting to look at is how we wrap our collections to make them bindable: quite a job! More over the model and the viewModel list are no more synched... The list object itself is synched but the operation on the collection will be made on the viewModel collection and no more on the model collection. In this case, adding or removing a friend's name will affect only the ViewModel and not the model.

Pros and Cons

Pros:

  • The name of the properties exposed to your views can be different from those in the business object
  • It's very easy to understand the code when you read it again, even a few months later

Cons:

  • It's a very boring job to re-create the properties of the viewModel to map those from the BO
  • Collection and Set of the model are no more synched with the ViewModel
  • Copy-cut code can leads to error, especially when raising INotifyPropertyChanged events where case matters

N.B.: I've found an article of Josh Smith on this subject that you may find useful too.

Shout it kick it on DotNetKicks.com

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here