public MainViewModel(IAppEventObservable appEvents) { // Tomamos un C# event y lo convertimos a un Observable. // Este Observable retornara el estado de la conneccion a Internet var isConnected = Observable.FromEventPattern <ConnectivityChangedEventArgs> (h => Connectivity.ConnectivityChanged += h, h => Connectivity.ConnectivityChanged -= h) .Select(IsDeviceConnected); // Observamos cuando el valor de la propiedad `Name` cambie usando `WhenAnyValue` var nameChanged = this.WhenAnyValue(x => x.Name) .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler); // Observamos cuando el valor de la propiedad `LastName` cambie usando `WhenAnyValue` var lastNameChanged = this.WhenAnyValue(x => x.LastName) .Throttle(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler); // Tomamos 3 Observables distintos y lo combinamos usando CombineLatest. // El Observable resultante es un IObservable<bool> el cual decidira si un Commando se puede ejecutar. // Para el isConnected tenemos que usar `StartWith` ya que este Observable no nos va a notificar hasta cuando // ocurra un cambio en la conneccion pero necesitamos el estado actual. var canExecuteCreate = isConnected.StartWith(GetCurrentNetworkState()) .CombineLatest(nameChanged, lastNameChanged, (connected, name, lastName) => !string.IsNullOrWhiteSpace(name) && !string.IsNullOrWhiteSpace(lastName) && connected); // Creamos un ReactiveCommand al cual usara como `canExecute` el Observable `canExecuteCreate` // Esto hara que cuando haya un cambio en cualquiera de los observables de ese pipeline este Commando reacionara a esto. CreateCommand = ReactiveCommand.CreateFromTask(ExecuteCreate, canExecuteCreate); // Creamos un segundo ReactiveCommand SubmitCommand = ReactiveCommand.Create(ExecuteSubmit); var isAppInBackground = appEvents.IsInBackground(); // Combinamos dos observables y el observable resultante lo llevamos a un // OAPH utilizando `ToProperty` var changed = nameChanged.CombineLatest(lastNameChanged, (name, lastName) => $"{lastName}, {name}") .ToProperty(this, nameof(FullName), out _fullName) .DisposeWith(ViewModelSubscriptions); // Nos subscribimos al pipelione del ReactiveCommand y cuando este completa // invocamos un segundo ReactiveCommand utilizando `InvokeCommand` CreateCommand .Select(a => Unit.Default) .InvokeCommand(SubmitCommand) .DisposeWith(ViewModelSubscriptions); // Nos subscribimos al pipelione del ReactiveCommand y si ocurre una Exception durante su ejecucion // nos subscribimos a ella CreateCommand .ThrownExceptions .Subscribe(error => { // Aqui podemos actual en base al error }) .DisposeWith(ViewModelSubscriptions); //Tomando el resultado del ReactiveCommand y lo llevamos un OAPH utilizando `ToProperty` CreateCommand.ToProperty(this, nameof(LatestDocumentId), out _latestDocId); // Muestra de como podemos invocar un RactiveCommand desde cualquier Pipeline nameChanged .Where(x => x == "ReactiveUI") .Select(x => Unit.Default) .InvokeCommand(CreateCommand); // Podemos subscribirnos al Observable IsExecuting del Commando para verificar el estado de la ejecucion. SubmitCommand.IsExecuting .CombineLatest(CreateCommand.IsExecuting, (submitIsExecuting, createIsExecuting) => !submitIsExecuting && !createIsExecuting) .Skip(1) .Where(isExecuting => !isExecuting) .DistinctUntilChanged() .Subscribe(x => { // Aqui tenemos acceso a ejecutar cualquier accion o cambiar el valor de alguna propiedad. // Pero si ese es el caso mejor evaluas hacerlo con `InvokeCommand` o `ToProperty` dependiendo // Cual sea tu necesidad. Aqui solo te mostramos que es posible. }) .DisposeWith(ViewModelSubscriptions); var timedHasPassed = Observable.Interval(TimeSpan.FromMinutes(15)); // Tomamos 3 Observables y le hacer Merge. Cuando alguno de estos 3 Observables de este Pipeline // notifique y las condiciones se den se ejecutra el metodo dentro del Subscribe. isConnected.Where(connected => !connected) .Merge(isAppInBackground.Where(isInBackground => isInBackground)) .Merge(timedHasPassed.Select(a => true)) //Merge necesita que todos los Observables sean del mismo tipo .Subscribe(StopLongRunningService) .DisposeWith(ViewModelSubscriptions); }