public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false) { Contract.Requires(sender != null && sender is DependencyObject); var type = sender.GetType(); var propertyName = expression.GetMemberInfo().Name; var depSender = sender as DependencyObject; if (depSender == null) { this.Log().Warn("Tried to bind DP on a non-DependencyObject. Binding as POCO object", type.FullName, propertyName); var ret = new POCOObservableForProperty(); return ret.GetNotificationForProperty(sender, expression, beforeChanged); } if (beforeChanged == true) { this.Log().Warn("Tried to bind DO {0}.{1}, but DPs can't do beforeChanged. Binding as POCO object", type.FullName, propertyName); var ret = new POCOObservableForProperty(); return ret.GetNotificationForProperty(sender, expression, beforeChanged); } var dpFetcher = getDependencyPropertyFetcher(type, propertyName); if (dpFetcher == null) { this.Log().Warn("Tried to bind DO {0}.{1}, but DP doesn't exist. Binding as POCO object", type.FullName, propertyName); var ret = new POCOObservableForProperty(); return ret.GetNotificationForProperty(sender, expression, beforeChanged); } #if WINDOWS_UWP return Observable.Create<IObservedChange<object, object>>(subj => { var handler = new DependencyPropertyChangedCallback((o, e) => { subj.OnNext(new ObservedChange<object, object>(sender, expression)); }); var dependencyProperty = dpFetcher(); var token = depSender.RegisterPropertyChangedCallback(dependencyProperty, handler); return Disposable.Create(() => depSender.UnregisterPropertyChangedCallback(dependencyProperty, token)); }); #else var dpAndSubj = createAttachedProperty(type, propertyName); return Observable.Create<IObservedChange<object, object>>(obs => { BindingOperations.SetBinding(depSender, dpAndSubj.Item1, new Binding() { Source = depSender, Path = new PropertyPath(propertyName) }); var disp = dpAndSubj.Item2 .Where(x => x == sender) .Select(x => new ObservedChange<object, object>(x, expression)) .Subscribe(obs); // ClearBinding calls ClearValue http://stackoverflow.com/questions/1639219/clear-binding-in-silverlight-remove-data-binding-from-setbinding return new CompositeDisposable(Disposable.Create(() => depSender.ClearValue(dpAndSubj.Item1)), disp); }); #endif }
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false) { var type = sender.GetType(); var propertyName = expression.GetMemberInfo().Name; var dpd = DependencyPropertyDescriptor.FromProperty(getDependencyProperty(type, propertyName), type); return Observable.Create<IObservedChange<object, object>>(subj => { var handler = new EventHandler((o, e) => { subj.OnNext(new ObservedChange<object, object>(sender, expression)); }); dpd.AddValueChanged(sender, handler); return Disposable.Create(() => dpd.RemoveValueChanged(sender, handler)); }); }
public IObservable<IObservedChange<object, object>> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, bool beforeChanged = false) { var type = sender.GetType(); var propertyName = expression.GetMemberInfo().Name; var dpd = DependencyPropertyDescriptor.FromProperty(getDependencyProperty(type, propertyName), type); if (dpd == null) { this.Log().Error("Couldn't find dependency property " + propertyName + " on " + type.Name); throw new NullReferenceException("Couldn't find dependency property " + propertyName + " on " + type.Name); } return Observable.Create<IObservedChange<object, object>>(subj => { var handler = new EventHandler((o, e) => { subj.OnNext(new ObservedChange<object, object>(sender, expression)); }); dpd.AddValueChanged(sender, handler); return Disposable.Create(() => dpd.RemoveValueChanged(sender, handler)); }); }