/// <inheritdoc/>
        public IDisposable BindCommandToObject(ICommand command, object target, IObservable <object> commandParameter)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            commandParameter = commandParameter ?? Observable.Return(target);

            object latestParam = null;
            var    ctlDelegate = new ControlDelegate(
                x =>
            {
                if (command.CanExecute(latestParam))
                {
                    command.Execute(latestParam);
                }
            })
            {
                IsEnabled = command.CanExecute(latestParam)
            };

            var sel = new Selector("theAction:");

            // TODO how does this work? Is there an Action property?
            Reflection.GetValueSetterOrThrow(target.GetType().GetRuntimeProperty("Action"))(target, sel, null);

            var targetSetter = Reflection.GetValueSetterOrThrow(target.GetType().GetRuntimeProperty("Target"));

            targetSetter(target, ctlDelegate, null);
            var actionDisp = Disposable.Create(() => targetSetter(target, null, null));

            var enabledSetter = Reflection.GetValueSetterForProperty(target.GetType().GetRuntimeProperty("Enabled"));

            if (enabledSetter == null)
            {
                return(actionDisp);
            }

            // initial enabled state
            enabledSetter(target, command.CanExecute(latestParam), null);

            var compDisp = new CompositeDisposable(
                actionDisp,
                commandParameter.Subscribe(x => latestParam = x),
                Observable.FromEventPattern <EventHandler, EventArgs>(x => command.CanExecuteChanged += x, x => command.CanExecuteChanged -= x)
                .Select(_ => command.CanExecute(latestParam))
                .Subscribe(x =>
            {
                enabledSetter(target, x, null);
                ctlDelegate.IsEnabled = x;
            }));

            return(compDisp);
        }
Esempio n. 2
0
        private IDisposable BindToDirect <TTarget, TValue>(
            IObservable <TValue> @this,
            TTarget target,
            Expression viewExpression)
            where TTarget : class
        {
            var setter = Reflection.GetValueSetterOrThrow(viewExpression.GetMemberInfo());

            if (viewExpression.GetParent().NodeType == ExpressionType.Parameter)
            {
                return(@this.Subscribe(
                           x => setter(target, x, viewExpression.GetArgumentsArray()),
                           ex =>
                {
                    this.Log().ErrorException($"{viewExpression} Binding received an Exception!", ex);
                }));
            }

            var bindInfo = Observable.CombineLatest(
                @this,
                target.WhenAnyDynamic(viewExpression.GetParent(), x => x.Value),
                (val, host) => new { val, host });

            return(bindInfo
                   .Where(x => x.host != null)
                   .Subscribe(
                       x => setter(x.host, x.val, viewExpression.GetArgumentsArray()),
                       ex =>
            {
                this.Log().ErrorException($"{viewExpression} Binding received an Exception!", ex);
            }));
        }