Esempio n. 1
0
        string getPropertyValidationError(string propName)
        {
            PropertyExtraInfo pei;

            lock (allValidatedProperties) {
                if (!allValidatedProperties.Get(this.GetType()).TryGetValue(propName, out pei))
                {
                    return(null);
                }
            }

            foreach (var v in pei.ValidationAttributes)
            {
                try {
                    var ctx = new ValidationContext(this, null, null)
                    {
                        MemberName = propName
                    };
                    var getter = Reflection.GetValueFetcherForProperty(pei.Type, propName);
                    v.Validate(getter(this), ctx);
                } catch (Exception ex) {
                    this.Log().Info("{0:X}.{1} failed validation: {2}",
                                    this.GetHashCode(), propName, ex.Message);
                    return(ex.Message);
                }
            }

            return(null);
        }
Esempio n. 2
0
        public IReactiveBinding <TView, TViewModel, TProp> BindCommand <TView, TViewModel, TProp, TControl, TParam>(
            TViewModel viewModel,
            TView view,
            Expression <Func <TViewModel, TProp> > propertyName,
            Expression <Func <TView, TControl> > controlName,
            Func <TParam> withParameter,
            string toEvent = null)
            where TViewModel : class
            where TView : class, IViewFor <TViewModel>
            where TProp : ICommand
        {
            var ctlName        = Reflection.SimpleExpressionToPropertyName(controlName);
            var viewPropGetter = Reflection.GetValueFetcherForProperty(typeof(TView), ctlName);

            IObservable <TProp> changed;
            IDisposable         bindingDisposable = bindCommandInternal(viewModel, view, propertyName, viewPropGetter, Observable.Empty <object>(), toEvent, out changed, cmd => {
                var rc = cmd as IReactiveCommand;
                if (rc == null)
                {
                    return(Legacy.ReactiveCommand.Create(x => cmd.CanExecute(x), _ => cmd.Execute(withParameter())));
                }

                var ret = new ReactiveCommand(rc.CanExecuteObservable);
                ret.Subscribe(_ => rc.Execute(withParameter()));
                return(ret);
            });

            return(new ReactiveBinding <TView, TViewModel, TProp>(view, viewModel, new string[] { ctlName }, new string[] { Reflection.SimpleExpressionToPropertyName(propertyName) },
                                                                  changed, BindingDirection.OneWay, bindingDisposable));
        }
Esempio n. 3
0
        public IReactiveBinding <TView, TViewModel, TProp> BindCommand <TView, TViewModel, TProp>(
            TViewModel viewModel,
            TView view,
            Expression <Func <TViewModel, TProp> > propertyName,
            string toEvent = null)
            where TViewModel : class
            where TView : class, IViewFor <TViewModel>
            where TProp : ICommand
        {
            var ctlName        = Reflection.SimpleExpressionToPropertyName(propertyName);
            var viewPropGetter = Reflection.GetValueFetcherForProperty(typeof(TView), ctlName);

            IObservable <TProp> changed;
            IDisposable         disp = bindCommandInternal(viewModel, view, propertyName, viewPropGetter, Observable.Empty <object>(), toEvent, out changed);

            return(new ReactiveBinding <TView, TViewModel, TProp>(view, viewModel, new string[] { ctlName }, new string[] { ctlName },
                                                                  changed, BindingDirection.OneWay, disp));
        }
Esempio n. 4
0
        public IReactiveBinding <TView, TViewModel, TProp> BindCommand <TView, TViewModel, TProp, TControl, TParam>(
            TViewModel viewModel,
            TView view,
            Expression <Func <TViewModel, TProp> > propertyName,
            Expression <Func <TView, TControl> > controlName,
            IObservable <TParam> withParameter,
            string toEvent = null)
            where TViewModel : class
            where TView : class, IViewFor <TViewModel>
            where TProp : ICommand
        {
            var ctlName        = Reflection.SimpleExpressionToPropertyName(controlName);
            var viewPropGetter = Reflection.GetValueFetcherForProperty(typeof(TView), ctlName);

            IObservable <TProp> changed;
            IDisposable         bindingDisposable = bindCommandInternal(viewModel, view, propertyName, viewPropGetter, withParameter, toEvent, out changed);

            return(new ReactiveBinding <TView, TViewModel, TProp>(view, viewModel, new string[] { ctlName }, Reflection.ExpressionToPropertyNames(propertyName),
                                                                  changed, BindingDirection.OneWay, bindingDisposable));
        }
Esempio n. 5
0
        static void subscribeToExpressionChain <TSender, TValue>(
            TSender origSource,
            string origPath,
            object source,
            LinkedListNode <string> propertyNames,
            LinkedListNode <IDisposable> subscriptions,
            bool beforeChange,
            Subject <IObservedChange <TSender, TValue> > subject
            )
        {
            var    current    = propertyNames;
            var    currentSub = subscriptions;
            object currentObj = source;
            ObservedChange <TSender, TValue> obsCh;

            while (current.Next != null)
            {
                Func <object, object> getter = null;

                if (currentObj != null)
                {
                    getter = Reflection.GetValueFetcherForProperty(currentObj.GetType(), current.Value);

                    if (getter == null)
                    {
                        subscriptions.List.Where(x => x != null).ForEach(x => x.Dispose());
                        throw new ArgumentException(String.Format("Property '{0}' does not exist in expression", current.Value));
                    }

                    var capture = new { current, currentObj, getter, currentSub };

                    var toDispose = new IDisposable[2];

                    var valGetter = new ObservedChange <object, TValue>()
                    {
                        Sender       = capture.currentObj,
                        PropertyName = buildPropPathFromNodePtr(capture.current),
                        Value        = default(TValue),
                    };

                    TValue prevVal    = default(TValue);
                    bool   prevValSet = valGetter.TryGetValue(out prevVal);

                    toDispose[0] = notifyForProperty(currentObj, capture.current.Value, true).Subscribe(x => {
                        prevValSet = valGetter.TryGetValue(out prevVal);
                    });

                    toDispose[1] = notifyForProperty(currentObj, capture.current.Value, false).Subscribe(x => {
                        subscribeToExpressionChain(origSource, origPath, capture.getter(capture.currentObj), capture.current.Next, capture.currentSub.Next, beforeChange, subject);

                        TValue newVal;
                        if (!valGetter.TryGetValue(out newVal))
                        {
                            return;
                        }

                        if (prevValSet && EqualityComparer <TValue> .Default.Equals(prevVal, newVal))
                        {
                            return;
                        }

                        obsCh = new ObservedChange <TSender, TValue>()
                        {
                            Sender       = origSource,
                            PropertyName = origPath,
                            Value        = default(TValue),
                        };

                        TValue obsChVal;
                        if (obsCh.TryGetValue(out obsChVal))
                        {
                            obsCh.Value = obsChVal;
                            subject.OnNext(obsCh);
                        }
                    });

                    currentSub.Value = Disposable.Create(() => { toDispose[0].Dispose(); toDispose[1].Dispose(); });
                }

                current    = current.Next;
                currentSub = currentSub.Next;
                currentObj = getter != null?getter(currentObj) : null;
            }

            if (currentSub.Value != null)
            {
                currentSub.Value.Dispose();
            }

            if (currentObj == null)
            {
                return;
            }

            var propName    = current.Value;
            var finalGetter = Reflection.GetValueFetcherForProperty(currentObj.GetType(), current.Value);

            currentSub.Value = notifyForProperty(currentObj, propName, beforeChange).Subscribe(x => {
                obsCh = new ObservedChange <TSender, TValue>()
                {
                    Sender       = origSource,
                    PropertyName = origPath,
                    Value        = (TValue)finalGetter(currentObj),
                };

                subject.OnNext(obsCh);
            });
        }