Last active
August 29, 2015 14:21
-
-
Save Jalalx/aa23553650eab7e298a7 to your computer and use it in GitHub Desktop.
Implements INotifyPropertyChanged and MarshalByRefObject for interception in view models.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Implements <see cref="INotifyPropertyChanged"/> and <see cref="MarshalByRefObject"/> for interception in view models. | |
/// </summary> | |
public abstract class InterceptableViewModelBase : MarshalByRefObject, INotifyPropertyChanged | |
{ | |
/// <summary> | |
/// Occurs when a property value changes. | |
/// </summary> | |
public event PropertyChangedEventHandler PropertyChanged; | |
/// <summary> | |
/// Checks if a property already matches a desired value. Sets the property and | |
/// notifies listeners only when necessary. | |
/// </summary> | |
/// <typeparam name="T">Type of the property.</typeparam> | |
/// <param name="storage">Reference to a property with both getter and setter.</param> | |
/// <param name="value">Desired value for the property.</param> | |
/// <param name="propertyName">Name of the property used to notify listeners. This | |
/// value is optional and can be provided automatically when invoked from compilers that | |
/// support CallerMemberName.</param> | |
/// <returns>True if the value was changed, false if the existing value matched the | |
/// desired value.</returns> | |
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) | |
{ | |
if (object.Equals(storage, value)) return false; | |
storage = value; | |
this.OnPropertyChanged(propertyName); | |
return true; | |
} | |
/// <summary> | |
/// Notifies listeners that a property value has changed. | |
/// </summary> | |
/// <param name="propertyName">Name of the property used to notify listeners. This | |
/// value is optional and can be provided automatically when invoked from compilers | |
/// that support <see cref="CallerMemberNameAttribute"/>.</param> | |
protected void OnPropertyChanged(string propertyName) | |
{ | |
var eventHandler = this.PropertyChanged; | |
if (eventHandler != null) | |
{ | |
eventHandler(this, new PropertyChangedEventArgs(propertyName)); | |
} | |
} | |
/// <summary> | |
/// Raises this object's PropertyChanged event. | |
/// </summary> | |
/// <typeparam name="T">The type of the property that has a new value</typeparam> | |
/// <param name="propertyExpression">A Lambda expression representing the property that has a new value.</param> | |
protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression) | |
{ | |
var propertyName = ExtractPropertyName(propertyExpression); | |
this.OnPropertyChanged(propertyName); | |
} | |
/// <summary> | |
/// Extracts the property name from a property expression. | |
/// </summary> | |
/// <typeparam name="T">The object type containing the property specified in the expression.</typeparam> | |
/// <param name="propertyExpression">The property expression (e.g. p => p.PropertyName)</param> | |
/// <returns>The name of the property.</returns> | |
/// <exception cref="ArgumentNullException">Thrown if the <paramref name="propertyExpression"/> is null.</exception> | |
/// <exception cref="ArgumentException">Thrown when the expression is:<br/> | |
/// Not a <see cref="MemberExpression"/><br/> | |
/// The <see cref="MemberExpression"/> does not represent a property.<br/> | |
/// Or, the property is static. | |
/// </exception> | |
public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression) | |
{ | |
if (propertyExpression == null) | |
{ | |
throw new ArgumentNullException("propertyExpression"); | |
} | |
var memberExpression = propertyExpression.Body as MemberExpression; | |
if (memberExpression == null) | |
{ | |
throw new ArgumentException(Resources.PropertySupport_NotMemberAccessExpression_Exception, "propertyExpression"); | |
} | |
var property = memberExpression.Member as PropertyInfo; | |
if (property == null) | |
{ | |
throw new ArgumentException(Resources.PropertySupport_ExpressionNotProperty_Exception, "propertyExpression"); | |
} | |
var getMethod = property.GetMethod; | |
if (getMethod.IsStatic) | |
{ | |
throw new ArgumentException(Resources.PropertySupport_StaticExpression_Exception, "propertyExpression"); | |
} | |
return memberExpression.Member.Name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment