Start of work on PropertyChangedExtentsions

This commit is contained in:
Antony Male 2014-02-26 14:14:18 +00:00
parent 2a1329627f
commit d87fc070ce
4 changed files with 82 additions and 6 deletions

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace Stylet
{
public static class ExpressionExtensions
{
public static string NameForProperty<TDelegate>(this Expression<TDelegate> propertyExpression)
{
Expression body;
if (propertyExpression.Body is UnaryExpression)
body = ((UnaryExpression)propertyExpression.Body).Operand;
else
body = propertyExpression.Body;
var member = body as MemberExpression;
if (member == null)
throw new ArgumentException("Property must be a MemberExpression");
return member.Member.Name;
}
}
}

View File

@ -20,12 +20,7 @@ namespace Stylet
protected void NotifyOfPropertyChange<TProperty>(Expression<Func<TProperty>> property)
{
string propertyName;
if (property.Body is UnaryExpression)
propertyName = ((MemberExpression)((UnaryExpression)property.Body).Operand).Member.Name;
else
propertyName = ((MemberExpression)property.Body).Member.Name;
this.NotifyOfPropertyChange(propertyName);
this.NotifyOfPropertyChange(property.NameForProperty());
}
protected virtual void NotifyOfPropertyChange([CallerMemberName] string propertyName = "")

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Stylet
{
public static class PropertyChangedExtensions
{
private static ConditionalWeakTable<INotifyPropertyChanged, List<Listener> eventMapping = new ConditionalWeakTable<INotifyPropertyChanged, List<Listener>();
private static object eventMappingLock = new object();
private class Listener
{
public readonly string PropertyName;
public readonly EventHandler<PropertyChangedEventArgs> Handler;
public Listener(string propertyName, EventHandler<PropertyChangedEventArgs> handler)
{
this.PropertyName = propertyName;
this.Handler = handler;
}
}
public static void Bind<TClass, TMember>(this TClass item, Expression<Func<TClass, TMember>> selector, Action<TMember> handler) where TClass : INotifyPropertyChanged
{
var propertyName = selector.NameForProperty();
var compiledSelector = selector.Compile();
List<Listener> listeners;
EventHandler<PropertyChangedEventArgs> ourHandler;
lock (eventMappingLock)
{
if (!eventMapping.TryGetValue(item, out listeners))
{
listeners = new List<Listener>();
eventMapping.Add(item, listeners);
}
ourHandler = (s, e) => handler(compiledSelector(item));
listeners.Add(new Listener(propertyName, ourHandler));
}
PropertyChangedEventManager.AddHandler(item, ourHandler, propertyName);
}
}
}

View File

@ -56,12 +56,14 @@
<Compile Include="EventAggregator.cs" />
<Compile Include="EventCommand.cs" />
<Compile Include="Execute.cs" />
<Compile Include="ExpressionExtensions.cs" />
<Compile Include="IConductor.cs" />
<Compile Include="IoC.cs" />
<Compile Include="Bootstrapper.cs" />
<Compile Include="IScreen.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PropertyChangedBase.cs" />
<Compile Include="PropertyChangedExtensions.cs" />
<Compile Include="Screen.cs" />
<Compile Include="ScreenExtensions.cs" />
<Compile Include="StyletIoC\BuilderUpper.cs" />