コード例 #1
0
        public TimerStartCommandViewModel()
        {
            // ctorからカウント開始
            var ctorDateTime = DateTime.Now;

            MyTimer1 = Observable.Interval(TimeSpan.FromSeconds(1))
                       .Select(_ => DateTime.Now - ctorDateTime)
                       .ToReadOnlyReactivePropertySlim()
                       .AddTo(CompositeDisposable);

#if false
            // 1. DataTime.Now からの差分でカウント  ◆もう少しかっちょよい実装ない?
            var clickDateTime = DateTime.MinValue;
            MyTimer2 = Observable.Interval(TimeSpan.FromSeconds(1))
                       .Where(_ => clickDateTime != DateTime.MinValue)
                       .Select(_ => DateTime.Now - clickDateTime)
                       .ToReadOnlyReactivePropertySlim()
                       .AddTo(CompositeDisposable);

            StartCommand = new ReactiveCommand()
                           .WithSubscribe(() => clickDateTime = DateTime.Now, CompositeDisposable.Add);

            StopCommand = new ReactiveCommand()
                          .WithSubscribe(() => clickDateTime = DateTime.MinValue, CompositeDisposable.Add);
#else
            // 2. BooleanNotifier で管理。Command.CanExecute も取れるので良い感じ
            var timerRunning = new BooleanNotifier();       // BooleanNotifier は IDisposable じゃないので Good!
            //var timerRunning = new ReactivePropertySlim<bool>(initialValue: false).AddTo(CompositeDisposable);

            MyTimer2 = Observable.Interval(TimeSpan.FromSeconds(1))
                       .TakeWhile(_ => timerRunning.Value)
                       .Repeat()
                       .Select(sec => TimeSpan.FromSeconds(sec))
                       .ToReadOnlyReactivePropertySlim()
                       .AddTo(CompositeDisposable);

            StartCommand = timerRunning.Inverse()
                           .ToReactiveCommand(!timerRunning.Value)
                           .WithSubscribe(() => timerRunning.TurnOn(), CompositeDisposable.Add);

            // ◆BooleanNotifier は (Rpと違って) Subscribe 時に LatestValue を発行しないので初期値の指定が必要する
            StopCommand = timerRunning
                          .ToReactiveCommand(timerRunning.Value)
                          .WithSubscribe(() => timerRunning.TurnOff(), CompositeDisposable.Add);
#endif
        }
コード例 #2
0
ファイル: MainController.cs プロジェクト: whidbey/Wifinian
        public MainController(StartupAgent agent, IWlanWorker worker)
        {
            StartupAgent = agent ?? throw new ArgumentNullException(nameof(agent));

            Profiles = new ObservableCollection <ProfileItem>();
            BindingOperations.EnableCollectionSynchronization(Profiles, _profilesLock);

            NotifyIconContainer = new NotifyIconContainer();
            NotifyIconContainer.MouseLeftButtonClick  += OnMainWindowShowRequested;
            NotifyIconContainer.MouseRightButtonClick += OnMenuWindowShowRequested;

            this._worker = worker;

            IsUpdating = new BooleanNotifier();
            IsWorking  = new BooleanNotifier();

            ShowUpdatingTime();            // For debug
            ShowWorkingTime();             // For debug

            RushesRescan = new ReactiveProperty <bool>()
                           .AddTo(this.Subscription);

            EngagesPriority = new ReactiveProperty <bool>()
                              .AddTo(this.Subscription);
            EngagesPriority
            .Subscribe(_ => SetNotifyIconText())
            .AddTo(this.Subscription);

            #region Update

            RescanTimer = new ReactiveTimer(TimeSpan.FromSeconds(Settings.Current.RescanInterval))
                          .AddTo(this.Subscription);

            RescanCommand = IsUpdating
                            .Inverse()
                            .ObserveOnUIDispatcher()     // This is for thread access by ReactiveCommand.
                            .ToReactiveCommand();
            RescanCommand
            .Merge(EngagesPriority.Where(x => x).Select(x => x as object))
            .Merge(RescanTimer.Select(x => x as object))
            .Subscribe(async _ => await ScanNetworkAsync())
            .AddTo(this.Subscription);

            Settings.Current
            .ObserveProperty(x => x.RescanInterval)
            .Subscribe(rescanInterval => RescanTimer.Interval = TimeSpan.FromSeconds(rescanInterval))
            .AddTo(this.Subscription);

            RushesRescan
            .Subscribe(rushesRescan =>
            {
                if (rushesRescan)
                {
                    RescanTimer.Start();
                }
                else
                {
                    RescanTimer.Stop();
                }

                SetNotifyIconText();
            })
            .AddTo(this.Subscription);

            var networkRefreshed = Observable.FromEventPattern(
                h => _worker.NetworkRefreshed += h,
                h => _worker.NetworkRefreshed -= h);
            var availabilityChanged = Observable.FromEventPattern(
                h => _worker.AvailabilityChanged += h,
                h => _worker.AvailabilityChanged -= h);
            var interfaceChanged = Observable.FromEventPattern(
                h => _worker.InterfaceChanged += h,
                h => _worker.InterfaceChanged -= h);
            var connectionChanged = Observable.FromEventPattern(
                h => _worker.ConnectionChanged += h,
                h => _worker.ConnectionChanged -= h);
            var profileChanged = Observable.FromEventPattern(
                h => _worker.ProfileChanged += h,
                h => _worker.ProfileChanged -= h);
            Observable.Merge(networkRefreshed, availabilityChanged, interfaceChanged, connectionChanged, profileChanged)
            .Throttle(TimeSpan.FromMilliseconds(100))
            .Subscribe(async _ =>
            {
                if (RushesRescan.Value)
                {
                    RescanTimer.Start(TimeSpan.FromSeconds(Settings.Current.RescanInterval));                             // Wait for due time.
                }
                await LoadProfilesAsync();
            })
            .AddTo(this.Subscription);

            #endregion

            #region Close

            CloseCommand = new ReactiveProperty <bool>(true)
                           .ToReactiveCommand();
            CloseCommand
            .Subscribe(_ => _current.Shutdown())
            .AddTo(this.Subscription);

            #endregion
        }