MVVM- Model- INotifyPropertyChanged

Below given is the technique which is used in Silverlight MVVM Model in order to support View- ViewModel data binding:

Data Bind

ing

Data Binding is a core component of the MVVM pattern, for an introduction to Data Binding check out this article from Microsoft. At the core of Data Binding is the INotifyPropertyChanged interface. This deceptively simple interface is used to synchronize property changes in a bound object with the UI layer.

public interface INotifyPropertyChanged{event PropertyChangedEventHandler PropertyChanged;}

public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);

The interface exposes a single event PropertyChanged.
In addition to specifying that an individual property has changed the event can also indicate all properties
of the object have changed by using either a null reference or String.Empty as the property name
in the PropertyChangedEventArgs.

Below is a typical implementation of the INotifyPropertyChanged interface:

public class Address : INotifyPropertyChanged

{

private string _road;

public string Road

{

get

{

return _road;

}

set

{

if (_road != value)

{

_road = value;

RaisePropertyChanged(“Road”);

}

}

}

private void RaisePropertyChanged(string propertyName)

{

if (PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

#endregion

}

As you develop more and more classes that implement the INotifyPropertyChanged event you will quickly come across two common and quite frustrating issues: 1). The code required to check for changes and raise the PropertyChanged event for each property is incredibly repetitive and tedious. 2). Its very easy to make a mistake and provide the wrong property name for the PropertyChangedEventArgseither through failing to update code during refactoring or mistyping.

Simplifying the Property Setter Code

All of our property setter implementations follow the same basic pattern; compare the new value with the current value, and if the values differ
assign the new value to the property’s backing field and raise the appropriate PropertyChanged event.
We can write a generic method to achieve all of these steps as follows:

protected bool SetProperty<T>(ref T backingField, T value, string propertyName)

{

var changed = !EqualityComparer<T>.Default.Equals(backingField, value);

if (changed)

{

backingField = value;

RaisePropertyChanged(propertyName);

}

return changed;

}

The use of “ref” parameters can often point toward a poor design, however, in this case its hard to argue with the elegance of the resulting property setter code:

public string Road

{

get

{

return _road;

}

set

{

SetProperty(ref _road, value, “Road”);

}

}

The SetProperty method returns a boolean indicating whether the property was changed which can be used to by the property
setter code to implement additional post processing, for example:

if (SetProperty(ref _road, value, “Road”))

IsDirty = true;

In addition to this, by centralizing the property setter code we now have a
single place to add additional features such as validation (which will be
covered in the next article in the series).

Finally, for those of you using JetBrains Resharper (and seriously if you’re
not why not), it is very easy to add a live template for properties.

<TemplatesExport family=”Live Templates”>

<Template uid=”bdff1468-958d-466a-9269-d84c92b1f055″ shortcut=”mprop” description=”Model Property” text=”public $Type$ $Name$ { get { return _$BackingField$; } set { SetProperty(ref _$BackingField$, value, () =&gt; $Name$); }} private $Type$ _$BackingField$;$END$” reformat=”True” shortenQualifiedReferences=”True”>

<Categories />

<Variables>

<Variable name=”Type” expression=”guessExpectedType()” initialRange=”0″ />

<Variable name=”Name” expression=”” initialRange=”0″ />

<Variable name=”BackingField” expression=”decapitalize(Name)” initialRange=”0″ />

</Variables>

<CustomProperties />

</Template>

</TemplatesExport>

Verifying the Property Name

I’m going to present two methods for verifying the property name.

Method 1 – Reflection

The first method is simple but effective, using reflection to verify that the
property exists. Because reflection is quite costly the check is only performed
if the code is compiled with the DEBUG conditional
define. More sophisticated implementations could cache the property information
for better performance.

protected void RaisePropertyChanged(string propertyName)

{

VerifyPropertyName(propertyName);

if (PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

[Conditional(“DEBUG”), DebuggerStepThrough]

private void VerifyPropertyName(string propertyName)

{

if (GetType().IsVisible)

{

if (!string.IsNullOrEmpty(propertyName) && GetType().GetProperty(propertyName) == null)

throw new ArgumentException(“Property name does not exists on target object.”, “propertyName”);

}

}

The main problem with this mechanism is that the check is performed entirely at runtime.

Method 2 – LINQ Expression

The second method uses a LINQ Expression to determine the property name. This approach has the advantages of offering some degree of compile time checking, as well as better support for refactoring tools.
There is a small overhead as the expression tree has to be created for each property set, however, in most cases this should be negligible.

protected bool SetField<T>(ref T field, T value, Expression<Func<T>> propertyExpression)

{

var changed = !EqualityComparer<T>.Default.Equals(field, value);

if (changed)

{

field = value;

RaisePropertyChanged(ExtractPropertyName(propertyExpression));

}

return changed;

}

private static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)

{

var memberExpression = propertyExpression.Body as MemberExpression;

if (memberExpression == null)

throw new ArgumentException(“Expression must be a MemberExpression.”, “propertyExpression”);

return memberExpression.Member.Name;

}

To use this new mechanism we need to update our property set code as follows:

SetField(ref _road, value, () => Road);

Conclusion

The techniques presented here should help you create base classes for your Model classes that will
reduce a lot of the mundane code usually required whilst adding some degree of verification.Rich Text AreaToolbarBold (Ctrl + B)Italic (Ctrl + I)Strikethrough (Alt + Shift + D)Unordered list (Alt + Shift + U)Ordered list (Alt + Shift + O)Blockquote (Alt + Shift + Q)Align Left (Alt + Shift + L)Align Center (Alt + Shift + C)Align Right (Alt + Shift + R)Insert/edit link (Alt + Shift + A)Unlink (Alt + Shift + S)Insert More Tag (Alt + Shift + T)Toggle spellchecker (Alt + Shift + N)▼
Toggle fullscreen mode (Alt + Shift + G)Show/Hide Kitchen Sink (Alt + Shift + Z)WP-Filebase
FormatFormat▼
UnderlineAlign Full (Alt + Shift + J)Select text color▼
Paste as Plain TextPaste from WordRemove formattingInsert custom characterOutdentIndentUndo (Ctrl + Z)Redo (Ctrl + Y)Help (Alt + Shift + H)

Below given is the technique which is used in Silverlight MVVM Model in order to support View- ViewModel data binding:

Data Binding
Data Binding is a core component of the MVVM pattern, for an introduction to Data Binding check out this article from Microsoft. At the core of Data Binding is the INotifyPropertyChanged interface. This deceptively simple interface is used to synchronize property changes in a bound object with the UI layer.
public interface INotifyPropertyChanged{event PropertyChangedEventHandler PropertyChanged;}
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
The interface exposes a single event PropertyChanged.
In addition to specifying that an individual property has changed the event can also indicate all properties
of the object have changed by using either a null reference or String.Empty as the property name
in the PropertyChangedEventArgs.

Below is a typical implementation of the INotifyPropertyChanged interface:
public class Address : INotifyPropertyChanged
{
private string _road;
public string Road
{
get
{
return _road;
}
set
{
if (_road != value)
{
_road = value;
RaisePropertyChanged(“Road”);
}
}
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
As you develop more and more classes that implement the INotifyPropertyChanged event you will quickly come across two common and quite frustrating issues: 1). The code required to check for changes and raise the PropertyChanged event for each property is incredibly repetitive and tedious. 2). Its very easy to make a mistake and provide the wrong property name for the PropertyChangedEventArgseither through failing to update code during refactoring or mistyping.
Simplifying the Property Setter Code
All of our property setter implementations follow the same basic pattern; compare the new value with the current value, and if the values differ
assign the new value to the property’s backing field and raise the appropriate PropertyChanged event.
We can write a generic method to achieve all of these steps as follows:
protected bool SetProperty(ref T backingField, T value, string propertyName)
{
var changed = !EqualityComparer.Default.Equals(backingField, value);
if (changed)
{
backingField = value;
RaisePropertyChanged(propertyName);
}
return changed;
}
The use of “ref” parameters can often point toward a poor design, however, in this case its hard to argue with the elegance of the resulting property setter code:
public string Road
{
get
{
return _road;
}
set
{
SetProperty(ref _road, value, “Road”);
}
}
The SetProperty method returns a boolean indicating whether the property was changed which can be used to by the property
setter code to implement additional post processing, for example:
if (SetProperty(ref _road, value, “Road”))
IsDirty = true;
In addition to this, by centralizing the property setter code we now have a
single place to add additional features such as validation (which will be
covered in the next article in the series).
Finally, for those of you using JetBrains Resharper (and seriously if you’re
not why not), it is very easy to add a live template for properties.

Verifying the Property Name
I’m going to present two methods for verifying the property name.
Method 1 – Reflection
The first method is simple but effective, using reflection to verify that the
property exists. Because reflection is quite costly the check is only performed
if the code is compiled with the DEBUG conditional
define. More sophisticated implementations could cache the property information
for better performance.
protected void RaisePropertyChanged(string propertyName)
{
VerifyPropertyName(propertyName);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
[Conditional(“DEBUG”), DebuggerStepThrough]
private void VerifyPropertyName(string propertyName)
{
if (GetType().IsVisible)
{
if (!string.IsNullOrEmpty(propertyName) && GetType().GetProperty(propertyName) == null)
throw new ArgumentException(“Property name does not exists on target object.”, “propertyName”);
}
}
The main problem with this mechanism is that the check is performed entirely at runtime.
Method 2 – LINQ Expression
The second method uses a LINQ Expression to determine the property name. This approach has the advantages of offering some degree of compile time checking, as well as better support for refactoring tools.
There is a small overhead as the expression tree has to be created for each property set, however, in most cases this should be negligible.
protected bool SetField(ref T field, T value, Expression<Func> propertyExpression)
{
var changed = !EqualityComparer.Default.Equals(field, value);
if (changed)
{
field = value;
RaisePropertyChanged(ExtractPropertyName(propertyExpression));
}
return changed;
}
private static string ExtractPropertyName(Expression<Func> propertyExpression)
{
var memberExpression = propertyExpression.Body as MemberExpression;
if (memberExpression == null)
throw new ArgumentException(“Expression must be a MemberExpression.”, “propertyExpression”);
return memberExpression.Member.Name;
}
To use this new mechanism we need to update our property set code as follows:
SetField(ref _road, value, () => Road);
Conclusion
The techniques presented here should help you create base classes for your Model classes that will
reduce a lot of the mundane code usually required whilst adding some degree of verification.
Path: