Пример #1
0
        public void IgnoreInitErrorAndForceNotify()
        {
            var rp = new ReactiveProperty <string>(mode: ReactivePropertyMode.Default | ReactivePropertyMode.IgnoreInitialValidationError)
                     .SetValidateNotifyError(x => string.IsNullOrEmpty(x) ? "error" : null);

            rp.HasErrors.IsFalse();
            rp.ForceNotify();
            rp.HasErrors.IsTrue();
        }
        public void ForceNotify()
        {
            var rp        = new ReactiveProperty <int>(0);
            var collector = new List <int>();

            rp.Subscribe(collector.Add);

            collector.Is(0);
            rp.ForceNotify();
            collector.Is(0, 0);
        }
Пример #3
0
        public BaseSetting()
        {
            // 通知可能なプロパティを取得し、それらに変更があればSettingChangedを発火させる
            var notifyProperties = GetType().GetProperties()
                                   .Where(x => x.PropertyType.GetInterfaces().Any(y => y == typeof(INotifyPropertyChanged)) && x.Name != nameof(SettingChanged));

            foreach (var p in notifyProperties)
            {
                var o = p.GetValue(this) as INotifyPropertyChanged;
                if (o != null)
                {
                    o.PropertyChanged += (s, e) => _settingChanged.ForceNotify();
                }
            }
        }
Пример #4
0
        public MainWindowViewModel()
        {
            DatabaseValue = new ReactiveProperty <string>();
            InitCommand   = new ReactiveCommand <string>()
                            .WithSubscribe(isDatabaseEmpty =>
            {
                _dbValueUpdating.SwitchValue();
                using (Disposable.Create(() => _dbValueUpdating.SwitchValue()))
                {
                    DatabaseValue.Value = bool.Parse(isDatabaseEmpty) ? null : "xxxx";
                    DatabaseValue.ForceNotify();
                }
            });

            InputValue = DatabaseValue.ToReactiveProperty();

            CommandText = Observable.Merge(
                DatabaseValue.Select(x => IsDbValueEmpty(x)).Select(x => x ? "A" : "B"),
                InputValue.Where(_ => !_dbValueUpdating.Value).Select(_ => "A"))
                          .ToReadOnlyReactiveProperty();
        }
Пример #5
0
        internal HandleViewModel(Handle handle, Train train)
        {
            HandleType = handle
                         .ToReactivePropertyAsSynchronized(x => x.HandleType)
                         .AddTo(disposable);

            PowerNotches = handle
                           .ToReactivePropertyAsSynchronized(x => x.PowerNotches, ignoreValidationErrorValue: true)
                           .AddTo(disposable);

            PowerNotches.Subscribe(_ => train.ApplyPowerNotchesToCar()).AddTo(disposable);

            BrakeNotches = handle
                           .ToReactivePropertyAsSynchronized(x => x.BrakeNotches, ignoreValidationErrorValue: true)
                           .SetValidateNotifyError(x =>
            {
                if (x == 0 && train.Device.HoldBrake)
                {
                    return("BrakeNotches must be at least 1 if HoldBrake is set.");
                }

                return(null);
            })
                           .AddTo(disposable);

            BrakeNotches.Subscribe(_ => train.ApplyBrakeNotchesToCar()).AddTo(disposable);

            PowerNotchReduceSteps = handle
                                    .ToReactivePropertyAsSynchronized(x => x.PowerNotchReduceSteps)
                                    .AddTo(disposable);

            HandleBehaviour = handle
                              .ToReactivePropertyAsSynchronized(x => x.HandleBehaviour)
                              .AddTo(disposable);

            LocoBrake = handle
                        .ToReactivePropertyAsSynchronized(x => x.LocoBrake)
                        .AddTo(disposable);

            LocoBrakeNotches = handle
                               .ToReactivePropertyAsSynchronized(x => x.LocoBrakeNotches)
                               .AddTo(disposable);

            LocoBrakeNotches.Subscribe(_ => train.ApplyLocoBrakeNotchesToCar()).AddTo(disposable);

            DriverPowerNotches = handle
                                 .ToReactivePropertyAsSynchronized(x => x.DriverPowerNotches, ignoreValidationErrorValue: true)
                                 .AddTo(disposable);

            DriverBrakeNotches = handle
                                 .ToReactivePropertyAsSynchronized(x => x.DriverBrakeNotches, ignoreValidationErrorValue: true)
                                 .AddTo(disposable);

            PowerNotches
            .SetValidateNotifyError(x =>
            {
                if (x < DriverPowerNotches.Value)
                {
                    return("DriverPowerNotches must be less than or equal to PowerNotches.");
                }

                return(null);
            })
            .Subscribe(_ => DriverPowerNotches.ForceValidate())
            .AddTo(disposable);

            PowerNotches
            .ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => PowerNotches.ForceNotify())
            .AddTo(disposable);

            BrakeNotches
            .SetValidateNotifyError(x =>
            {
                if (x < DriverBrakeNotches.Value)
                {
                    return("DriverBrakeNotches must be less than or equal to BrakeNotches.");
                }

                return(null);
            })
            .Subscribe(_ => DriverBrakeNotches.ForceValidate())
            .AddTo(disposable);

            BrakeNotches
            .ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => BrakeNotches.ForceNotify())
            .AddTo(disposable);

            DriverPowerNotches
            .SetValidateNotifyError(x =>
            {
                if (x > PowerNotches.Value)
                {
                    return("DriverPowerNotches must be less than or equal to PowerNotches.");
                }

                return(null);
            })
            .Subscribe(_ => PowerNotches.ForceValidate())
            .AddTo(disposable);

            DriverPowerNotches
            .ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => DriverPowerNotches.ForceNotify())
            .AddTo(disposable);

            DriverBrakeNotches
            .SetValidateNotifyError(x =>
            {
                if (x > BrakeNotches.Value)
                {
                    return("DriverBrakeNotches must be less than or equal to BrakeNotches.");
                }

                return(null);
            })
            .Subscribe(_ => BrakeNotches.ForceValidate())
            .AddTo(disposable);

            DriverBrakeNotches
            .ObserveHasErrors
            .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
            .Where(x => !x)
            .Subscribe(_ => DriverBrakeNotches.ForceNotify())
            .AddTo(disposable);
        }
        public void ForceNotify()
        {
            var rp = new ReactiveProperty<int>(0);
            var collecter = new List<int>();
            rp.Subscribe(collecter.Add);

            collecter.Is(0);
            rp.ForceNotify();
            collecter.Is(0, 0);
        }
Пример #7
0
 void UpdateLoop()
 {
     UpdateLogic.ForceNotify();
 }
Пример #8
0
        public FeedGroupPageViewModel(HohoemaApp hohoemaApp, PageManager pageManager, Views.Service.ContentSelectDialogService contentSelectDialogService)
            : base(hohoemaApp, pageManager)
        {
            ContentSelectDialogService = contentSelectDialogService;

            IsDeleted = new ReactiveProperty <bool>();

            FeedGroupName     = new ReactiveProperty <string>();
            MylistFeedSources = new ObservableCollection <FeedItemSourceListItem>();
            TagFeedSources    = new ObservableCollection <FeedItemSourceListItem>();
            UserFeedSources   = new ObservableCollection <FeedItemSourceListItem>();

            HasMylistFeedSource = MylistFeedSources.ObserveProperty(x => x.Count)
                                  .Select(x => x > 0)
                                  .ToReadOnlyReactiveProperty();
            HasTagFeedSource = TagFeedSources.ObserveProperty(x => x.Count)
                               .Select(x => x > 0)
                               .ToReadOnlyReactiveProperty();
            HasUserFeedSource = UserFeedSources.ObserveProperty(x => x.Count)
                                .Select(x => x > 0)
                                .ToReadOnlyReactiveProperty();


            MylistFavItems = new ObservableCollection <FollowItemInfo>();
            TagFavItems    = new ObservableCollection <FollowItemInfo>();
            UserFavItems   = new ObservableCollection <FollowItemInfo>();

            SelectFromFavItems = new ReactiveProperty <bool>(true);
            SelectedFavInfo    = new ReactiveProperty <FollowItemInfo>();

            FavItemType        = new ReactiveProperty <FollowItemType>();
            FeedSourceId       = new ReactiveProperty <string>();
            FeedSourceItemName = new ReactiveProperty <string>();
            ExistFeedSource    = new ReactiveProperty <bool>();
            IsPublicFeedSource = new ReactiveProperty <bool>();

            CanUseFeedSource = Observable.CombineLatest(
                ExistFeedSource,
                IsPublicFeedSource
                )
                               .Select(x => x.All(y => y))
                               .ToReactiveProperty();

            FavItemType.Subscribe(x =>
            {
                FeedSourceId.Value    = "";
                ExistFeedSource.Value = false;

                FeedSourceItemName.Value = "";


                // お気に入りアイテムがある場合は、「お気に入りから選択」をデフォルトに
                switch (x)
                {
                case FollowItemType.Tag:
                    SelectFromFavItems.Value = TagFavItems.Count > 0;
                    break;

                case FollowItemType.Mylist:
                    SelectFromFavItems.Value = MylistFavItems.Count > 0;
                    break;

                case FollowItemType.User:
                    SelectFromFavItems.Value = UserFavItems.Count > 0;
                    break;

                default:
                    break;
                }
            });

            FeedSourceId.ToUnit()
            .Subscribe(_ =>
            {
                ExistFeedSource.Value    = false;
                FeedSourceItemName.Value = "";
            });

            Observable.Merge(
                SelectFromFavItems.ToUnit(),

                SelectedFavInfo.ToUnit(),

                FavItemType.ToUnit(),
                FeedSourceId.ToUnit().Throttle(TimeSpan.FromSeconds(1))
                )
            .Subscribe(async x =>
            {
                if (SelectFromFavItems.Value)
                {
                    ExistFeedSource.Value    = SelectedFavInfo.Value != null;
                    IsPublicFeedSource.Value = true;
                    FeedSourceItemName.Value = "";
                    return;
                }

                ExistFeedSource.Value = false;

                if (FavItemType.Value == FollowItemType.Tag)
                {
                    ExistFeedSource.Value    = !string.IsNullOrWhiteSpace(FeedSourceId.Value);
                    IsPublicFeedSource.Value = true;
                    FeedSourceItemName.Value = FeedSourceId.Value;
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(FeedSourceId.Value))
                    {
                        ExistFeedSource.Value = false;
                    }
                    else
                    {
                        if (FavItemType.Value == FollowItemType.Mylist)
                        {
                            try
                            {
                                var mylistRes = await HohoemaApp.ContentFinder.GetMylistGroupDetail(FeedSourceId.Value);
                                var mylist    = mylistRes?.MylistGroup;

                                if (mylist != null)
                                {
                                    ExistFeedSource.Value    = true;
                                    IsPublicFeedSource.Value = mylist.IsPublic;
                                    FeedSourceItemName.Value = Mntone.Nico2.StringExtention.DecodeUTF8(mylist.Name);
                                }
                            }
                            catch
                            {
                                ExistFeedSource.Value = false;
                            }
                        }
                        else if (FavItemType.Value == FollowItemType.User)
                        {
                            try
                            {
                                var user = await HohoemaApp.ContentFinder.GetUserDetail(FeedSourceId.Value);
                                if (user != null)
                                {
                                    ExistFeedSource.Value    = true;
                                    IsPublicFeedSource.Value = !user.IsOwnerVideoPrivate;
                                    FeedSourceItemName.Value = user.Nickname;
                                }
                            }
                            catch
                            {
                                ExistFeedSource.Value = false;
                            }
                        }

                        if (!ExistFeedSource.Value)
                        {
                            IsPublicFeedSource.Value = false;
                            FeedSourceItemName.Value = "";
                        }
                    }
                }
            });

            AddFeedCommand =
                Observable.CombineLatest(
                    ExistFeedSource,
                    IsPublicFeedSource
                    )
                .Select(x => x.All(y => y == true))
                .ToReactiveCommand();

            AddFeedCommand.Subscribe(_ =>
            {
                string name = "";
                string id   = "";

                if (SelectFromFavItems.Value)
                {
                    var favInfo = SelectedFavInfo.Value;
                    name        = favInfo.Name;
                    id          = favInfo.Id;

                    if (favInfo.FollowItemType != FavItemType.Value)
                    {
                        throw new Exception();
                    }
                }
                else
                {
                    // idからMylistGroupを引く
                    // 公開されていない場合にはエラー
                    id   = FeedSourceId.Value;
                    name = FeedSourceItemName.Value;

                    FeedSourceItemName.Value = "";
                    FeedSourceId.Value       = "";
                }

                var favManager  = HohoemaApp.FollowManager;
                var feedManager = HohoemaApp.FeedManager;
                IFeedSource feedSource;
                switch (FavItemType.Value)
                {
                case FollowItemType.Tag:

                    feedSource = FeedGroup.AddTagFeedSource(id);
                    if (feedSource != null)
                    {
                        var favInfo = favManager.Tag.FollowInfoItems.SingleOrDefault(x => x.Id == id);
                        if (favInfo != null)
                        {
                            TagFavItems.Remove(favInfo);
                        }

                        TagFeedSources.Add(new FeedItemSourceListItem(feedSource, this));
                    }

                    break;

                case FollowItemType.Mylist:

                    feedSource = FeedGroup.AddMylistFeedSource(name, id);
                    if (feedSource != null)
                    {
                        var favInfo = favManager.Mylist.FollowInfoItems.SingleOrDefault(x => x.Id == id);
                        if (favInfo != null)
                        {
                            MylistFavItems.Remove(favInfo);
                        }

                        MylistFeedSources.Add(new FeedItemSourceListItem(feedSource, this));
                    }

                    break;

                case FollowItemType.User:

                    feedSource = FeedGroup.AddUserFeedSource(name, id);
                    if (feedSource != null)
                    {
                        var favInfo = favManager.User.FollowInfoItems.SingleOrDefault(x => x.Id == id);
                        if (favInfo != null)
                        {
                            UserFavItems.Remove(favInfo);
                        }

                        UserFeedSources.Add(new FeedItemSourceListItem(feedSource, this));
                    }

                    break;

                default:
                    break;
                }

                HohoemaApp.FeedManager.SaveOne(FeedGroup);
            });

            RenameApplyCommand = FeedGroupName
                                 .Where(x => HohoemaApp.FeedManager != null && x != null)
                                 .Select(x => HohoemaApp.FeedManager.CanAddLabel(x))
                                 .ToReactiveCommand();

            RenameApplyCommand.Subscribe(async _ =>
            {
                if (await FeedGroup.Rename(FeedGroupName.Value))
                {
                    UpdateTitle(FeedGroup.Label);
                }

                FeedGroupName.ForceNotify();
            });
        }
Пример #9
0
        /// <summary>
        /// 新しいインスタンスを初期化します。
        /// </summary>
        public MainWindowViewModel()
        {
            // set

            PdfPath  = new ReactiveProperty <string>();
            Password = new ReactiveProperty <string>();

            var isExistsPdf = PdfPath
                              .Select(x => x ?? string.Empty)
                              .Select(x => x.Trim('"'))
                              .Select(x => File.Exists(x));

            var hasPassword = Password
                              .Select(x => !string.IsNullOrWhiteSpace(x));

            Status = Observable.CombineLatest(
                isExistsPdf,
                hasPassword,
                (x, y) => !x
                        ? "PDF ファイルを選択してください"
                        : !y
                            ? "パスワードを入力してください"
                            : "[ENTER] キーまたは [UNLOCK] ボタンを押してください")
                     .ToReactiveProperty();

            SelectFileCommand = new ReactiveCommand();

            UnlockCommand = Observable.CombineLatest(
                isExistsPdf,
                hasPassword,
                (x, y) => x && y)
                            .ToReactiveCommand();

            // subscribe

            SelectFileCommand
            .Subscribe(_ =>
            {
                var dialog = new OpenFileDialog()
                {
                    Filter = "PDF (*.pdf)|*.pdf"
                };
                if (dialog.ShowDialog() == true)
                {
                    PdfPath.Value = dialog.FileName;
                }
            });

            UnlockCommand
            .Subscribe(_ =>
            {
                var trimmedPdfPath = PdfPath.Value.Trim('"');

                if (File.Exists(trimmedPdfPath))
                {
                    var destinationPath =
                        PathHelper.CreateUniquePath(
                            Path.GetDirectoryName(trimmedPdfPath),
                            Path.ChangeExtension(trimmedPdfPath, null) + "_unlocked.pdf");
                    try
                    {
                        PdfUnlocker.Unlock(trimmedPdfPath, destinationPath, Password.Value);
                        Password.Value = null;
                        Status.Value   = "PDF ファイルのパスワードを解除しました";
                        PathHelper.OpenExplorerWithSelected(destinationPath);
                    }
                    catch (BadPasswordException)
                    {
                        Password.Value = null;
                        Status.Value   = "正しいパスワードを入力してください";
                    }
                    catch (InvalidPdfException)
                    {
                        Status.Value = "PDF ファイルが開けませんでした";
                    }
                }
                else
                {
                    PdfPath.ForceNotify();
                }
            });
        }