Introduction
MVVM is a design pattern for XAML based applications. It ensures separation of concerns, test-ability and maintainability. The viewmodel should contain all the properties that will be bound to the view. Almost every element you want to bind to the view, you have to add a property in the viewmodel to control it, even if you want to insert a loading wheel. That's very powerful thanks to the Binding mechanism, especially with the use of notification with INotifyPropertyChanged
interface.
Problem
However, the drawback of this pattern is that the number of properties will be high especially when you have a rich view. This will make your viewmodel look too long. Consider that for every property, you will need almost the following 6 lines of code:
private string _name;
public String Name
{
get { return _name; }
set { Set(ref _name = value); }
}
Imagine if you have only 10 properties in each viewmodel. Then, you will have 60 lines of code only for properties!
Solution
A first solution is to use the Fody extension to decorate a property with an attribute. This will enable notification of the bounded property without using a backed field or implementing the INotifyPropertyChanged
. Fody will inject the needed code at compile-time. Then you will have only 2 lines of code for each one:
[AlsoNotifyFor("Name")]
public String Name { get; set; }
Let's make it even better and reduce the 20 lines to only 1 line. Is that possible? Yes! All we need is to have an object that can contain many objects with different types and each one is notifiable. Fortunately, the ObservableCollection<object>
do. Consider using the " =
" operation than the Add(..)
method, because Add
doesn't enable notification. To face this detail, Windows Store 8.1 templates (Hub app and GridView
app) comes with an object called ObservableDictionary
. Which is also good in that it uses the key string to identify a value rather than a number.
Implementation
public ObservableDictionary Model { get; set; }
Model = new ObservableDictionary();
Model.Add("Fullname", "Houssem Dellai");