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
        }
Example #2
0
        /// <inheritdoc/>
        public IObservable <IObservedChange <object, object> > GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = false, bool suppressWarnings = false)
        {
            Contract.Requires(sender != null && sender is DependencyObject);
            var type      = sender.GetType();
            var depSender = sender as DependencyObject;

            if (depSender == null)
            {
                if (!suppressWarnings)
                {
                    this.Log().Warn(
                        CultureInfo.InvariantCulture,
                        "Tried to bind DP on a non-DependencyObject. Binding as POCO object",
                        type.FullName,
                        propertyName);
                }

                var ret = new POCOObservableForProperty();
                return(ret.GetNotificationForProperty(sender, expression, propertyName, beforeChanged));
            }

            if (beforeChanged == true)
            {
                this.Log().Warn(
                    CultureInfo.InvariantCulture,
                    "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, propertyName, beforeChanged));
            }

            var dpFetcher = GetDependencyPropertyFetcher(type, propertyName);

            if (dpFetcher == null)
            {
                this.Log().Warn(
                    CultureInfo.InvariantCulture,
                    "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, propertyName, beforeChanged));
            }

            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));
            }));
        }
        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;

            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));
            }

            var dpAndSubj = createAttachedProperty(type, propertyName);

            return(Observable.Create <IObservedChange <object, object> >(obs => {
                BindingOperations.SetBinding(sender as DependencyObject, dpAndSubj.Item1,
                                             new Binding()
                {
                    Source = sender as DependencyObject, 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(() => (sender as DependencyObject).ClearValue(dpAndSubj.Item1)), disp);
            }));
        }