private static ReactiveCommand FireCommandEx( IGeneralBus bus, Func <Object, Command> commandFunc, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null, TimeSpan?responseTimeout = null, TimeSpan?ackTimeout = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async _ => await Task.Run(() => { var c = commandFunc(_); if (c != null) { bus.Fire(c, userErrorMsg, responseTimeout, ackTimeout); } }); var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions .SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex)) .ObserveOn(MainThreadScheduler).Subscribe(result => { //This will return the recovery option returned from the registered user error handler //right now this is a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
public ConnectViewModel() { ConnectText = new ReactiveProperty <string>("Connect"); Host = new ReactiveProperty <string>("127.0.0.1:3306").SetValidateNotifyError(x => ConnectViewModelValidation.Host.Validate(x).ErrorMessages.FirstOrDefault()); Username = new ReactiveProperty <string>("root").SetValidateNotifyError(x => ConnectViewModelValidation.Username.Validate(x).ErrorMessages.FirstOrDefault()); Password = new ReactiveProperty <string>("").SetValidateNotifyError(x => ConnectViewModelValidation.Password.Validate(x).ErrorMessages.FirstOrDefault()); Database = new ReactiveProperty <string>("").SetValidateNotifyError(x => ConnectViewModelValidation.Database.Validate(x).ErrorMessages.FirstOrDefault()); ResourcePath = new ReactiveProperty <string>("") .SetValidateNotifyError(x => ConnectViewModelValidation.ResourcePath.Validate(x).ErrorMessages.FirstOrDefault()); var canConnect = this.WhenAnyValue(x => x.Host.Value, x => x.Username.Value, x => x.Password.Value, x => x.Database.Value, x => x.ResourcePath.Value) .Select(_ => ConnectViewModelValidation.MySql.Validate(this).Succeeded); Connect = ReactiveCommand.CreateFromTask(ConnectImpl, canConnect); Exit = ReactiveCommand.Create(ExitImpl); SelectResourceFile = ReactiveCommand.CreateFromTask(SelectResourceFileImpl); }
private static ReactiveCommand PublishEvents( IBus bus, IEnumerable <Func <Event> > events, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async _ => await Task.Run(() => { foreach (var func in events) { bus.Publish(func()); } }); var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions .SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex)) .ObserveOn(MainThreadScheduler).Subscribe(result => { //This will return the recovery option returned from the registered user error handler //right now this is a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
private ReactiveCommand GetSelectSourceFileCommand() { var command = ReactiveCommand.Create(SelectSourceFile, null, DispatcherScheduler.Current); _disposables.Add(command); return(command); }
private static ReactiveCommand FireCommands( ICommandPublisher bus, IEnumerable <Func <Command> > commands, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null, TimeSpan?responseTimeout = null, TimeSpan?ackTimeout = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async _ => await Task.Run(() => { foreach (var func in commands) { bus.Send(func(), userErrorMsg, responseTimeout, ackTimeout); } }); var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions #pragma warning disable CS0618 // Type or member is obsolete .SelectMany(ex => UserError.Throw(userErrorMsg, ex)) #pragma warning restore CS0618 // Type or member is obsolete .ObserveOn(MainThreadScheduler).Subscribe(result => { //This will return the recovery option returned from the registered user error handler //right now this is a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
public SelectItemViewModel() { Search = new ReactiveProperty <string>(); Items = new ReactiveList <Item>(); SelectedItem = new ReactiveProperty <Item>(); Search.WhenAnyValue(x => x.Value) .Throttle(TimeSpan.FromSeconds(1)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(search => { Items.Clear(); // It's not possible to add an item more than once so remove existing shop items from the search var items = ResourceService.Instance.Items.Where(item => ShopService.Instance.Items.All(x => x.ItemNumber != item.ItemNumber)); if (!string.IsNullOrWhiteSpace(search)) { var split = search.Split(' '); items = items.Where(item => split.All(word => item.Name.Contains(word, StringComparison.OrdinalIgnoreCase))); } Items.AddRange(items); }); var canSelect = SelectedItem.WhenAnyValue(x => x.Value).Select(x => x != null); Select = ReactiveCommand.Create(SelectImpl, canSelect); Cancel = ReactiveCommand.Create(CancelImpl); }
public YoutubeSongViewModel(YoutubeSong wrapped, Func <string> downloadPathFunc) : base(wrapped) { this.hasThumbnail = this.WhenAnyValue(x => x.Thumbnail) .Select(x => x != null) .ToProperty(this, x => x.HasThumbnail); // Wait for the opening of the context menu to download the YouTube information this.WhenAnyValue(x => x.IsContextMenuOpen) .FirstAsync(x => x) .SelectMany(_ => this.LoadContextMenu().ToObservable()) .Subscribe(); // We have to set a dummy here, so that we can connect the commands this.isDownloading = Observable.Never <bool>().ToProperty(this, x => x.IsDownloading); this.DownloadVideoCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x), x => this.DownloadVideo((VideoInfo)x, downloadPathFunc())); this.DownloadAudioCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.IsDownloading).Select(x => !x), x => this.DownloadAudio((VideoInfo)x, downloadPathFunc())); this.isDownloading = this.DownloadVideoCommand.IsExecuting .CombineLatest(this.DownloadAudioCommand.IsExecuting, (x1, x2) => x1 || x2) .ToProperty(this, x => x.IsDownloading); }
private static ReactiveCommand FromAction( Action <object> action, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async _ => await Task.Run(() => action(_)); var cmd = ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions #pragma warning disable CS0618 // Type or member is obsolete .ObserveOn(MainThreadScheduler).SelectMany(ex => UserError.Throw(userErrorMsg ?? ex.Message, ex)) #pragma warning restore CS0618 // Type or member is obsolete .Subscribe(result => { //This will return the recovery option returned from the registered user error handler //right now this is a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
private static ReactiveCommand <object, Unit> PublishEventsEx( IPublisher bus, IEnumerable <Func <object, Event> > eventFuncs, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async x => await Task.Run(() => { foreach (var func in eventFuncs) { bus.Publish(func(x)); } }); var cmd = canExecute == null? ReactiveCommand.CreateFromTask(task, outputScheduler : scheduler) : ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions .SelectMany(ex => Interactions.Errors.Handle(new UserError(userErrorMsg ?? ex.Message, ex))) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(result => { // This will return the recovery option returned from the registered user error handler, // e.g. a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
public SettingsViewModel(IUserInterface userInterface, IUserDialogs userDialogs, IDotaClientDistanceLoader distanceLoader, ISettingsManager <Settings> settingsManager) { _userDialogs = userDialogs; Settings = settingsManager.LoadAsync().ToObservable().ToReactiveProperty(); SaveSettingsCommand = ReactiveCommand.CreateFromTask <Settings>(settingsManager.SaveAsync); ToggleDarkModeCommand = ReactiveCommand.Create <bool>(userInterface.DarkMode); LoadDistanceCommand = ReactiveCommand.CreateFromTask <Settings>(distanceLoader.LoadAsync); BrowseDota2FolderCommand = ReactiveCommand.CreateFromTask(OpenFolderDialog); BrowseDota2FolderCommand.Where(value => !string.IsNullOrWhiteSpace(value)) .SubscribeOnUIDispatcher() .Subscribe(value => Settings.Value.Dota2FolderPath = value); this.WhenAnyValue(vm => vm.Settings.Value.DarkMode) .InvokeCommand(ToggleDarkModeCommand); this.WhenAnyValue(vm => vm.Settings.Value.Dota2FolderPath) .Where(value => !string.IsNullOrWhiteSpace(value)) .Select(_ => Settings.Value) .ObserveOnUIDispatcher() .InvokeCommand(LoadDistanceCommand); }
public MainWindowViewModel() { TorrentSelected = new ReactiveCommand(); DownloadAll = new ReactiveAsyncCommand(); DeleteSelected = new ReactiveAsyncCommand(); DeleteSelected.Subscribe(new AnonymousObserver<object>(x => { App.streamza.RemoveTorrent(_selectedTorrent.id); })); DownloadAll.Subscribe(new AnonymousObserver<object>(x => { var sel = _selectedTorrent; var s = new VistaFolderBrowserDialog(); var res = s.ShowDialog(); if (!res.HasValue || res.Value != true) return; var files = App.streamza.GetTorrentFiles(sel); foreach (var file in files) { var uri = App.streamza.GetDownloadLink(file); var cl = new WebClient(); var path = Path.Combine(s.SelectedPath, file.path); if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path)); cl.DownloadFile(new Uri(uri), path); } // This probably works best when there are lots of small files; doesn't // offer any improvement when there are only a couple of large files. // TODO: Check file count and set parallelism appropriately //Parallel.ForEach(files, // new ParallelOptions { MaxDegreeOfParallelism = 4 }, // (file) => // { // var uri = App.streamza.GetDownloadLink(file); // var cl = new WebClient(); // var path = Path.Combine(s.SelectedPath, file.path); // if (!Directory.Exists(Path.GetDirectoryName(path))) // Directory.CreateDirectory(Path.GetDirectoryName(path)); // cl.DownloadFile(new Uri(uri), path); // }); })); _torrents = App.streamza.Torrents; Observable .Start(() => { Observable .Interval(TimeSpan.FromSeconds(10)) .Subscribe(i => { if (FetchingFiles) return; _torrents = App.streamza.Torrents; raisePropertyChanged("Torrents"); }); }); }
public SelectEffectViewModel() { Search = new ReactiveProperty <string>(); Effects = new ReactiveList <Effect>(); SelectedEffect = new ReactiveProperty <Effect>(); Search.WhenAnyValue(x => x.Value) .Throttle(TimeSpan.FromSeconds(1)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(search => { Effects.Clear(); if (string.IsNullOrWhiteSpace(search)) { Effects.AddRange(ResourceService.Instance.Effects); return; } var split = search.Split(' '); var effects = ResourceService.Instance.Effects .Where(effect => split.All(word => effect.Name.Contains(word, StringComparison.OrdinalIgnoreCase))) .ToArray(); Effects.AddRange(effects); }); var canSelect = SelectedEffect.WhenAnyValue(x => x.Value).Select(x => x != null); Select = ReactiveCommand.Create(SelectImpl, canSelect); Cancel = ReactiveCommand.Create(CancelImpl); }
private ReactiveCommand GetStartCalculationCommand() { var canExecuteObservable = CanStartCalculationExecuteObservable(); var command = ReactiveCommand.Create(StartCalculation, canExecuteObservable, DispatcherScheduler.Current); _disposables.Add(command); return(command); }
protected JobViewModelBase(T job, IScheduler scheduler) { Job = job; _scheduler = scheduler; _preChangeName = job.Name; Save = ReactiveCommand.Create(ExecuteSave, this.WhenAny(x => x.ValidationError, x => string.IsNullOrEmpty(x.Value))); }
public DownloadItemViewModel(Job job) { Job = job; Job.WhenAnyValue(j => j.Status).StartWith(job.Status).Subscribe(OnStatusUpdated); // update progress every 300ms Job.WhenAnyValue(j => j.TransferPercent) .Sample(TimeSpan.FromMilliseconds(300)) .Where(x => !job.IsFinished) .Subscribe(progress => { // on main thread System.Windows.Application.Current.Dispatcher.Invoke(() => { DownloadPercent = progress; DownloadPercentFormatted = $"{Math.Round(DownloadPercent)}%"; }); }); // update download speed every 1.5 seconds var lastUpdatedProgress = DateTime.Now; long bytesReceived = 0; Job.WhenAnyValue(j => j.TransferPercent) .Sample(TimeSpan.FromMilliseconds(1500)) .Where(x => !job.IsFinished) .Subscribe(progress => { // on main thread System.Windows.Application.Current.Dispatcher.Invoke(() => { var timespan = DateTime.Now - lastUpdatedProgress; var bytespan = Job.TransferredBytes - bytesReceived; if (timespan.TotalMilliseconds > 0) { var downloadSpeed = 1000 * bytespan / timespan.TotalMilliseconds; DownloadSpeedFormatted = $"{downloadSpeed.Bytes().ToString("#.0")}/s"; } bytesReceived = Job.TransferredBytes; lastUpdatedProgress = DateTime.Now; }); }); // update initial size only once Job.WhenAnyValue(j => j.TransferSize).Select(size => size.Bytes().ToString("#.0")).ToProperty(this, vm => vm.DownloadSizeFormatted, out _downloadSizeFormatted); // abort job on command CancelJob = ReactiveCommand.Create(() => { Job.Cancel(); }); // retry job RetryJob = ReactiveCommand.Create(() => { JobManager.RetryJob(Job); }); // delete job DeleteJob = ReactiveCommand.Create(() => { JobManager.DeleteJob(Job); }); // setup icon SetupFileIcon(); }
public override void Init() { RefreshCommand = ReactiveUI.ReactiveCommand.CreateFromTask(RefreshDevicesList) .AddDisposableTo(Disposables); this.WhenAnyValue(model => model.SelectedDevice) .Subscribe(deviceService.SelectDevice) .AddDisposableTo(Disposables) ; }
public EqualizerViewModel(Equalizer equalizer) { this.Equalizer = equalizer; this.SetToDefaultCommand = ReactiveCommand.Create( () => this.Equalizer.SetToDefault(), this.WhenAnyValue(x => x.Equalizer.IsEnabled)); this.CloseEqualizerCommand = ReactiveCommand.Create( () => this.Equalizer.SaveEqualizerSettings()); }
public EffectGroupViewModel(ShopEffectGroup effectGroup) { EffectGroup = effectGroup; AddEffect = ReactiveCommand.CreateFromTask(AddEffectImpl); Delete = ReactiveCommand.CreateFromTask(DeleteImpl); EffectGroup.WhenAnyValue(x => x.Name.Value) .Where(x => IsInitialized.Value) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => UpdateImpl()); }
public PriceViewModel(ShopPrice price) { Price = price; Delete = ReactiveCommand.CreateFromTask(DeleteImpl); Price.WhenAnyValue(_ => _.PeriodType.Value, _ => _.Period.Value, _ => _.Price.Value, _ => _.IsRefundable.Value, _ => _.Durability.Value, _ => _.IsEnabled.Value) .Where(x => IsInitialized.Value) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => UpdateImpl()); }
public EffectViewModel(ShopEffect effect) { Effect = effect; Change = ReactiveCommand.CreateFromTask(ChangeImpl); Delete = ReactiveCommand.CreateFromTask(DeleteImpl); Effect.WhenAnyValue(x => x.Effect.Value) .Where(x => IsInitialized.Value) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => UpdateImpl()); }
public AddCustomResolverViewModel() { Name = new ReactiveProperty <string>("").SetValidateNotifyError(s => { if (string.IsNullOrWhiteSpace(s)) { return("Name must not be empty"); } return(ExistingNames.Contains(s) ? $"Name {s} is already present in the server list" : null); }); OkCommand = ReactiveCommand.CreateFromTask(() => TryCloseAsync(true), Name.ObserveHasErrors.CombineLatest(Stamp.ObserveHasErrors, (a, b) => !a && !b)); CancelCommand = ReactiveCommand.CreateFromTask(() => TryCloseAsync(false)); }
public LoginViewModel() { var canLogin = this.WhenAnyValue( x => x.Email, x => x.Password, (em, pa) => !string.IsNullOrWhiteSpace(em) && !string.IsNullOrWhiteSpace(pa) && EmailIsValid(em)); LoginCommand = ReactiveCommand.CreateFromTask(async() => { await LoginAsync(); }, canLogin); LoginCommand.IsExecuting.ToProperty(this, x => x.IsLoading, out _isLoading); }
public ItemInfoViewModel(ShopItemInfo itemInfo) { ItemInfo = itemInfo; Delete = ReactiveCommand.CreateFromTask(DeleteImpl); ItemInfo.WhenAnyValue( x => x.PriceGroup.Value, x => x.EffectGroup.Value, x => x.DiscountPercentage.Value, x => x.IsEnabled.Value) .Where(x => IsInitialized.Value) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => UpdateImpl()); }
public UserViewModel(IScreen screen, User user, IUserRepository userRepository) { _userRepository = userRepository; HostScreen = screen; // Commands var canSubmit = this.WhenAny(e => e.Code, code => code.Value.IsValid()); Submit = ReactiveCommand.CreateFromTask(_ => userRepository.Submit(Model), canSubmit); Submit.Subscribe(result => MessageBox.Show(result ? "Success" : "Failure")); // Observe on UI thread Submit.ThrownExceptions.ObserveOn(RxApp.MainThreadScheduler) .Select(ex => new UserError("It will fail again, try anyway?", ex.Message)) .SelectMany(UserError.Throw) .Subscribe(resolution => { if (resolution == RecoveryOptionResult.RetryOperation) { Submit.Execute(); } }); // Model subscription this.WhenAnyValue(e => e.Model).Where(e => e != null).Subscribe(model => { Code = model.Code; Group = model.Group; }); Model = user; // Properties subscriptions this.WhenAnyValue(e => e.Group).Subscribe(group => Model.Group = group); this.WhenAnyValue(e => e.Code).Subscribe(code => Model.Code = code); // Subscribe to error handle UserError.RegisterHandler(async error => { // This shouldn't be a messagebox because is blocking the application, you must provide context and offer a resolution to the user not just showing "error" await Task.Delay(1); var message = new StringBuilder(); bool hasRecoveryOptions = error.ErrorCauseOrResolution.IsValid(); if (hasRecoveryOptions) { message.AppendLine(error.ErrorCauseOrResolution); } message.AppendLine(error.ErrorMessage); var result = MessageBox.Show(message.ToString(), "Alert!", hasRecoveryOptions ? MessageBoxButton.YesNo : MessageBoxButton.OK); return(hasRecoveryOptions && result == MessageBoxResult.Yes ? RecoveryOptionResult.RetryOperation : RecoveryOptionResult.CancelOperation); }); }
public ItemsViewModel() { AddItem = ReactiveCommand.CreateFromTask(AddItemImpl); Items = new ReactiveList <ShopItem>(); CurrentPage = new ReactiveProperty <int>(1); PageCount = new ReactiveProperty <int>(ShopService.Instance.Items.Count); Search = new ReactiveProperty <string>(""); ShopService.Instance.Items.Changed.Subscribe(_ => { PageCount.Value = GetFilteredItems().Count() / ItemsPerPage; UpdateItems(); }); _pageString = this.WhenAnyValue(x => x.CurrentPage.Value, x => x.PageCount.Value) .Select(x => $"{x.Item1} / {x.Item2}") .ToProperty(this, x => x.PageString); this.WhenAnyValue(x => x.PageCount.Value) .Subscribe(x => { if (CurrentPage.Value > x) { CurrentPage.Value = x; } UpdateItems(); }); this.WhenAnyValue(x => x.Search.Value) .Throttle(TimeSpan.FromSeconds(2)) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(_ => { PageCount.Value = GetFilteredItems().Count() / ItemsPerPage; UpdateItems(); }); var canNextPage = this.WhenAnyValue(x => x.CurrentPage.Value, x => x.PageCount.Value) .Select(x => x.Item1 < x.Item2); var canPrevPage = this.WhenAnyValue(x => x.CurrentPage.Value) .Select(x => x > 1); NextPage = ReactiveCommand.CreateFromTask(NextPageImpl, canNextPage); PrevPage = ReactiveCommand.CreateFromTask(PrevPageImpl, canPrevPage); }
public IssuesViewModel(INetworkConnectivityService networkConnectivityService, IWeeklyXamarinService weeklyXamarinService) { Ensure.ArgumentNotNull(networkConnectivityService, nameof(networkConnectivityService)); Ensure.ArgumentNotNull(weeklyXamarinService, nameof(weeklyXamarinService)); _networkConnectivityService = networkConnectivityService; _weeklyXamarinService = weeklyXamarinService; SearchResults = new ReactiveList <IssuesResult>(); // Here we're describing here, in a *declarative way*, the conditions in // which the Search command is enabled. Now our Command IsEnabled is // perfectly efficient, because we're only updating the UI in the scenario // when it should change. var canSearch = this.WhenAnyValue(vm => vm.SearchQuery, value => !string.IsNullOrWhiteSpace(value)); // ReactiveCommand has built-in support for background operations and // guarantees that this block will only run exactly once at a time, and // that the CanExecute will auto-disable and that property IsExecuting will // be set according whilst it is running. Search = ReactiveCommand.CreateAsyncObservable(canSearch, x => _weeklyXamarinService.Search(SearchQuery)); // ReactiveCommands are themselves IObservables, whose value are the results // from the async method, guaranteed to arrive on the UI thread. We're going // to take the list of search results that the background operation loaded, // and them into our SearchResults. Search.Subscribe(results => { SearchResults.Clear(); SearchResults.AddRange(results); }); // ThrownExceptions is any exception thrown from the CreateAsyncTask piped // to this Observable. Subscribing to this allows you to handle errors on // the UI thread. Search.ThrownExceptions .Subscribe(ex => { UserError.Throw("Potential Network Connectivity Error", ex); }); // Whenever the Search query changes, we're going to wait for one second // of "dead airtime", then automatically invoke the subscribe command. this.WhenAnyValue(x => x.SearchQuery) .Throttle(TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler) .InvokeCommand(this, x => x.Search); }
public override void Init() { deviceService.SelectedDevice .Do(device => Device = device) .ObserveOnDispatcher() .Subscribe() .AddDisposableTo(Disposables); SaveCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SaveDeviceSettings) .AddDisposableTo(Disposables); SavePermanentCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SavePermanentDeviceSettings) .AddDisposableTo(Disposables); ResetCommand = ReactiveUI.ReactiveCommand.CreateFromTask(ResetDevice) .AddDisposableTo(Disposables); LocateDeviceCommand = ReactiveUI.ReactiveCommand.CreateFromTask(LocateDevice) .AddDisposableTo(Disposables); LocateButtonText = "Start Blinking"; IsDeviceSelected = false; }
private static ReactiveCommand <object, Unit> SendCommandEx( IDispatcher bus, Func <object, Command> commandFunc, IObservable <bool> canExecute = null, IScheduler scheduler = null, string userErrorMsg = null, TimeSpan?responseTimeout = null, TimeSpan?ackTimeout = null) { if (scheduler == null) { scheduler = RxApp.MainThreadScheduler; } Func <object, Task> task = async x => await Task.Run(() => { var c = commandFunc(x); if (c != null) { bus.Send(c, userErrorMsg, responseTimeout, ackTimeout); } }); var cmd = canExecute == null? ReactiveCommand.CreateFromTask(task, outputScheduler : scheduler) : ReactiveCommand.CreateFromTask(task, canExecute, scheduler); cmd.ThrownExceptions .SelectMany(ex => Interactions.Errors.Handle(new UserError(userErrorMsg ?? ex.Message, ex))) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(result => { // This will return the recovery option returned from the registered user error handler, // e.g. a simple message box in the view code behind /* n.b. this forces evaluation/execution of the select many */ }); return(cmd); }
public ViewModel2( SynchronizationContext context, IObservable <string> name, IObservable <string> password, IObservable <int> progress) { name.ToProperty(this, x => x.UserName, out _userName); password.ToProperty(this, x => x.Password, out _password); progress.ToProperty(this, x => x.Progress, out _progress); CanUserLogin = this.WhenAnyValue( x => x.UserName, x => x.Password, (user, pass) => !string.IsNullOrWhiteSpace(user) && !string.IsNullOrWhiteSpace(pass) && user.Length >= 2 && pass.Length >= 3) .DistinctUntilChanged(); CmdLogin = ReactiveCommand.Create(() => CanUserLogin, CanUserLogin); //.InvokeCommand(CmdProcessLoginAsync); CmdProcessLoginAsync = ReactiveCommand.CreateFromTask(() => { return(Task.Run(() => { Progress = 0; while (Progress <= 100) { Progress += 10; Thread.Sleep(100); } })); }, CanUserLogin); //CmdCancel = ReactiveCommand.CreateCombined(); }
public MainViewViewModel(IUserDialogs userDialogs, IDotaClientDistancePatcher distancePatcher, SettingsViewModel settingsViewModel, IScreen hostScreen) { SettingsViewModel = settingsViewModel; HostScreen = hostScreen; var pathCanExecute = this.WhenAnyValue( model => model.SettingsViewModel.Settings.Value.X32Client.Distance.Value, model => model.SettingsViewModel.Settings.Value.X64Client.Distance.Value, (x32, x64) => new[] { x32, x64 }) .Select(items => items.All(value => value >= 1000 && value <= 9999)); PatchCommand = ReactiveCommand.CreateFromTask <Settings>(distancePatcher.PatchAsync, pathCanExecute); PatchCommand .SubscribeOnUIDispatcher() .Subscribe(_ => { userDialogs.Alert("Done!"); }); PatchCommand.ThrownExceptions .SubscribeOnUIDispatcher() .Subscribe(exception => userDialogs.Alert("Error occurred!")); }
public PullRequestDetailViewModel( IPullRequestService pullRequestsService, IPullRequestSessionManager sessionManager, IModelServiceFactory modelServiceFactory, IUsageTracker usageTracker, ITeamExplorerContext teamExplorerContext, IPullRequestFilesViewModel files, ISyncSubmodulesCommand syncSubmodulesCommand, IViewViewModelFactory viewViewModelFactory, IGitService gitService, IOpenIssueishDocumentCommand openDocumentCommand, [Import(AllowDefault = true)] JoinableTaskContext joinableTaskContext) { Guard.ArgumentNotNull(pullRequestsService, nameof(pullRequestsService)); Guard.ArgumentNotNull(sessionManager, nameof(sessionManager)); Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory)); Guard.ArgumentNotNull(usageTracker, nameof(usageTracker)); Guard.ArgumentNotNull(teamExplorerContext, nameof(teamExplorerContext)); Guard.ArgumentNotNull(syncSubmodulesCommand, nameof(syncSubmodulesCommand)); Guard.ArgumentNotNull(viewViewModelFactory, nameof(viewViewModelFactory)); Guard.ArgumentNotNull(gitService, nameof(gitService)); Guard.ArgumentNotNull(openDocumentCommand, nameof(openDocumentCommand)); this.pullRequestsService = pullRequestsService; this.sessionManager = sessionManager; this.modelServiceFactory = modelServiceFactory; this.usageTracker = usageTracker; this.teamExplorerContext = teamExplorerContext; this.syncSubmodulesCommand = syncSubmodulesCommand; this.viewViewModelFactory = viewViewModelFactory; this.gitService = gitService; this.openDocumentCommand = openDocumentCommand; JoinableTaskContext = joinableTaskContext ?? ThreadHelper.JoinableTaskContext; Files = files; Checkout = ReactiveCommand.CreateFromObservable( DoCheckout, this.WhenAnyValue(x => x.CheckoutState) .Cast <CheckoutCommandState>() .Select(x => x != null && x.IsEnabled)); Checkout.IsExecuting.Subscribe(x => isInCheckout = x); SubscribeOperationError(Checkout); Pull = ReactiveCommand.CreateFromObservable( DoPull, this.WhenAnyValue(x => x.UpdateState) .Cast <UpdateCommandState>() .Select(x => x != null && x.PullEnabled)); SubscribeOperationError(Pull); Push = ReactiveCommand.CreateFromObservable( DoPush, this.WhenAnyValue(x => x.UpdateState) .Cast <UpdateCommandState>() .Select(x => x != null && x.PushEnabled)); SubscribeOperationError(Push); SyncSubmodules = ReactiveCommand.CreateFromTask( DoSyncSubmodules, this.WhenAnyValue(x => x.UpdateState) .Cast <UpdateCommandState>() .Select(x => x != null && x.SyncSubmodulesEnabled)); SyncSubmodules.Subscribe(_ => Refresh().ToObservable()); SubscribeOperationError(SyncSubmodules); OpenConversation = ReactiveCommand.Create(DoOpenConversation); OpenOnGitHub = ReactiveCommand.Create(DoOpenDetailsUrl); ShowReview = ReactiveCommand.Create <IPullRequestReviewSummaryViewModel>(DoShowReview); ShowAnnotations = ReactiveCommand.Create <IPullRequestCheckViewModel>(DoShowAnnotations); }