public CreateFolderViewModel(CreateFolderState state, ICloudViewModel owner, ICloud provider) { _path = owner .WhenAnyValue(x => x.CurrentPath) .ToProperty(this, x => x.Path); this.ValidationRule( x => x.Name, name => !string.IsNullOrWhiteSpace(name), "Folder name shouldn't be empty."); var pathRule = this.ValidationRule( x => x.Path, path => !string.IsNullOrWhiteSpace(path), "Path shouldn't be empty"); Create = ReactiveCommand.CreateFromTask( () => provider.CreateFolder(Path, Name), this.IsValid()); _isLoading = Create.IsExecuting .ToProperty(this, x => x.IsLoading); var canInteract = owner .WhenAnyValue(x => x.CanInteract) .Skip(1) .StartWith(true); var canOpen = this .WhenAnyValue(x => x.IsVisible) .Select(visible => !visible) .CombineLatest( canInteract, pathRule.WhenAnyValue(x => x.IsValid), (visible, interact, path) => visible && provider.CanCreateFolder && interact && path); var canClose = this .WhenAnyValue(x => x.IsVisible) .Select(visible => visible); Open = ReactiveCommand.Create(() => { }, canOpen); Close = ReactiveCommand.Create(() => { }, canClose); Open.Select(unit => true) .Merge(Close.Select(unit => false)) .Subscribe(visible => IsVisible = visible); Close.Subscribe(x => Name = string.Empty); Create.InvokeCommand(Close); _hasErrorMessage = Create .ThrownExceptions .Select(exception => true) .Merge(Close.Select(unit => false)) .ToProperty(this, x => x.HasErrorMessage); _errorMessage = Create .ThrownExceptions .Select(exception => exception.Message) .Log(this, $"Create folder error occured in {provider.Name}") .Merge(Close.Select(unit => string.Empty)) .ToProperty(this, x => x.ErrorMessage); Name = state.Name; IsVisible = state.IsVisible; this.WhenAnyValue(x => x.Name) .Subscribe(name => state.Name = name); this.WhenAnyValue(x => x.IsVisible) .Subscribe(visible => state.IsVisible = visible); }