Playing Around with System.Reactive Again
August 17, 2009
Further to my previous post, Erik Meijer commented that an overload to the FromEvent method is available to convert from generic event handlers to the specific ones used by much of the BCL. So the code from the previous post would look something like this now:
#region Ctor
public MainPage()
{
InitializeComponent();
var mouseEventSource = Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
eh => new MouseEventHandler(eh), // Conversion
eh => this.MouseMove += eh, // Subscribe
eh => this.MouseMove -= eh); // Unsubscribe
_mouseMoveSubscription = mouseEventSource.Subscribe(OnMouseMove);
}
#endregion
private void OnMouseMove(Event<MouseEventArgs> e)
{
var position = e.EventArgs.GetPosition(this);
Debug.WriteLine("Mouse moved. Position: {0}.", position);
}
This solves one of my major gripes. Exciting times!
A base class for Domain Models
August 14, 2009
I just wrote a base class that I’m going to derive all of my notifying Domain Models from. It solves the horror of passing around the property name of a changing property in the INotifyPropertyChanged implementation. This has the enormous benefit of being able to check your Property Names at compile-time and also allows you to keep everything in sync when using tools like Resharper (if you don’t use Resharper – then you really should!) to rename things. It uses lambda expressions to specify the Property that’s changing.
public abstract class ModelBase<T> : INotifyPropertyChanged where T : ModelBase<T>
{
#region Events
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Public Methods
public static string GetPropertyName<R>(Expression<Func<T, R>> expression)
{
var memberExpression = expression.Body as MemberExpression;
if (memberExpression == null)
{
throw new ArgumentException("'expression' should be a member expression");
}
var propertyName = memberExpression.Member.Name;
return propertyName;
}
#endregion
#region Protected Methods
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void RaisePropertyChanged<R>(Expression<Func<T, R>> expression)
{
var propertyName = GetPropertyName(expression);
this.OnPropertyChanged(propertyName);
}
#endregion
}