private _propertyTree CreatePropertyTree(Expression exp, _propertyTree child = null) { var mExp = exp as MemberExpression; if (mExp == null) { return(null); } var pi = mExp.Member as PropertyInfo; if (pi == null) { throw new ArgumentException("式木からプロパティを取得できません。"); } var tree = new _propertyTree(pi, child); var parent = CreatePropertyTree(mExp.Expression, tree); if (parent != null) { return(parent); } return(tree); }
private IDisposable createChildWeakEventListener <TChild>(PropertyTreeChangedWeakEventListener <TChild> listener, _propertyTree tree, PropertyChangedEventHandler handler) where TChild : INotifyPropertyChanged { Action createCldLstnr = null; Action dispCldLstnr = null; if (tree != null) { var methodName = MethodBase.GetCurrentMethod().Name; createCldLstnr = () => { var pi = tree.PropertyInfo; var getterMi = pi.GetGetMethod(); var getterType = typeof(Func <,>).MakeGenericType(pi.ReflectedType, pi.PropertyType); var childValue = Delegate .CreateDelegate(getterType, getterMi) .DynamicInvoke(listener._eventSrc); // プロパティに対してリスナーを作成。 var childType = childValue.GetType(); object childListener = null; if (typeof(INotifyPropertyChanged).IsAssignableFrom(childType)) { childListener = typeof(PropertyTreeChangedWeakEventListener <>) .MakeGenericType(childType) .GetConstructor(new Type[] { childType }) .Invoke(new object[] { childValue }); dispCldLstnr = () => { (childListener as IDisposable)?.Dispose(); }; listener .GetType() .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) .MakeGenericMethod(childType) .Invoke(listener, new object[] { childListener, tree.Child, handler }); } }; } createCldLstnr?.Invoke(); return(new LivetWeakEventListener <PropertyChangedEventHandler, PropertyChangedEventArgs>( h => new PropertyChangedEventHandler(h), h => { _eventSrc.PropertyChanged += h; }, h => { _eventSrc.PropertyChanged -= h; dispCldLstnr?.Invoke(); }, (s, e) => { if (e.PropertyName == tree.PropertyInfo.Name) { handler(s, e); dispCldLstnr?.Invoke(); createCldLstnr?.Invoke(); } })); }
public _propertyTree(PropertyInfo pi, _propertyTree child) { PropertyInfo = pi; Child = child; }