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