public SearchRecipeViewModel(ISettings settings, ILogger logger) { this._searchRecipe = new SearchRecipe(settings, logger).AddTo(this.CompositeDisposable); // Property // 現在ページ this.CurrentPage = this._searchRecipe.CurrentPage.ToReadOnlyReactiveProperty().AddTo(this.CompositeDisposable); // 最大ページ数 this.MaxPage = this._searchRecipe.MaxPage.ToReadOnlyReactiveProperty().AddTo(this.CompositeDisposable); // 複数ページフラグ this.IsMultiPage = this.MaxPage.Select(x => x >= 2).ToReadOnlyReactiveProperty().AddTo(this.CompositeDisposable); // ページリスト this.PageList = this.MaxPage .CombineLatest(this.CurrentPage, (max, current) => (max, current)) .Select(x => Enumerable .Range(x.current - 4, 10) .Where(i => i >= 1 && i <= x.max) .ToArray() ) .ToReadOnlyReactivePropertySlim() .AddTo(this.CompositeDisposable); // 検索ワード this.SearchWord = this._searchRecipe.SearchWord.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 検索対象フラグ:タイトル this.IsTitleSearchTarget = this._searchRecipe.IsTitleSearchTarget.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 検索対象フラグ:材料 this.IsIngredientSearchTarget = this._searchRecipe.IsIngredientSearchTarget.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 検索対象フラグ:手順 this.IsStepSearchTarget = this._searchRecipe.IsStepSearchTarget.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 最終利用日 this.LastUsedDate = this._searchRecipe.LastUsedDate.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 最終利用日以前フラグ this.IsBeforeLastUsedDate = this._searchRecipe.IsBeforeLastUsedDate.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 利用回数 this.UsageCount = this._searchRecipe.UsageCount.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 利用回数以上フラグ this.IsUsageCountMoreThan = this._searchRecipe.IsUsageCountMoreThan.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // アーカイブを含むかどうかのフラグ this.IncludingArchive = this._searchRecipe.IncludingArchive.ToReactivePropertyAsSynchronized(x => x.Value).AddTo(this.CompositeDisposable); // 検索結果 this.SearchResult = this._searchRecipe .Result .Select(x => x.Select(r => Creator.CreateRecipeViewModelInstance(settings, logger, r) ).ToArray() ).ToReadOnlyReactiveProperty() .AddTo(this.CompositeDisposable); // タグ候補 this.TagList = this._searchRecipe.TagList.ToReadOnlyReactiveCollection().AddTo(this.CompositeDisposable); // 評価 this.Ratings = this._searchRecipe.Ratings.ToReadOnlyReactiveCollection().AddTo(this.CompositeDisposable); // 追加したソート条件 this.SortConditions = this._searchRecipe.SortConditions.ToReadOnlyReactiveCollection().AddTo(this.CompositeDisposable); // 検索条件リスト this.SortItems = this._searchRecipe.SortItems.ToReadOnlyReactiveCollection().AddTo(this.CompositeDisposable); // 検索条件プラグインリスト this.SearchConditionPlugins = this._searchRecipe.SearchConditionPlugins.ToReadOnlyReactiveCollection().AddTo(this.CompositeDisposable); // 追加されたプラグイン検索条件 this.PluginSearchConditions = this._searchRecipe.PluginSearchConditions.ToReadOnlyReactiveCollection(x => { var(view, viewModel) = Creator.CreateRecipeSearchConditionViewAndViewModel(x); return(new ViewViewModelPair <UserControl, IRecipeSearchConditionViewModel>(view, viewModel)); }).AddTo(this.CompositeDisposable); // ロード中フラグ this.IsBusy = this._searchRecipe.IsBusy.ToReadOnlyReactiveProperty().AddTo(this.CompositeDisposable); // Command // 検索 this.SearchCommand.Subscribe(_ => this._searchRecipe.Search()).AddTo(this.CompositeDisposable); // ソート条件追加 this.AddSortConditionCommand.Subscribe(() => this._searchRecipe.AddSortCondition()).AddTo(this.CompositeDisposable); // ソート条件削除 this.RemoveSortConditionCommand.Subscribe(s => this._searchRecipe.RemoveSortCondition(s)).AddTo(this.CompositeDisposable); // プラグイン検索条件追加 this.AddPluginSearchConditionCommand.Where(p => p != null).Subscribe(p => this._searchRecipe .AddPluginSearchCondition(p) ).AddTo(this.CompositeDisposable); // プラグイン検索条件削除 this.RemovePluginSearchConditionCommand.Subscribe(c => this._searchRecipe.RemovePluginSearchCondition(c.RecipeSearchCondition)).AddTo(this.CompositeDisposable); // 前ページへ戻る this.PreviousCommand = this.CurrentPage.Select(c => c > 1).ToReactiveCommand().AddTo(this.CompositeDisposable); this.PreviousCommand.Subscribe(() => { this._searchRecipe.GoToPreviousPage(); }).AddTo(this.CompositeDisposable); // 次ページへ進む this.NextCommand = this.CurrentPage.CombineLatest(this.MaxPage, (c, m) => c < m).ToReactiveCommand().AddTo(this.CompositeDisposable); this.NextCommand.Subscribe(() => { this._searchRecipe.GoToNextPage(); }).AddTo(this.CompositeDisposable); // ページ遷移 this.TransitionCommand.Subscribe(page => { this._searchRecipe.PageTransition(page); }).AddTo(this.CompositeDisposable); // レシピエディタ起動 this.EditRecipeCommand.Subscribe(rvm => { var vm = new RecipeDetailViewModel(settings, logger); vm.RecipeViewModel.Value = rvm; vm.RecipeView.Value = Creator.CreateRecipeEditorViewInstance(settings, logger, rvm); this.Messenger.Raise(new TransitionMessage(vm, "OpenEditRecipeWindow")); }).AddTo(this.CompositeDisposable); // レシピ削除 this.DeleteRecipeCommand.Subscribe(rvm => { var vm = new DialogWindowViewModel("削除確認", "レシピを削除します。よろしいですか。", DialogWindowViewModel.DialogResult.Yes, DialogWindowViewModel.DialogResult.No ); using (vm) { this.Messenger.Raise(new TransitionMessage(vm, TransitionMode.Modal, "OpenDialogWindow")); if (vm.Result != DialogWindowViewModel.DialogResult.Yes) { return; } rvm.DeleteRecipeCommand.Execute(this.Messenger); // 結果を再読込 this.SearchCommand.Execute(); } }).AddTo(this.CompositeDisposable); }
public AddRecipeViewModel(ISettings settings, ILogger logger, Method methods) { // 追加方法のリスト if ((methods & Method.Original) != 0) { this.MethodList.Add(new OriginalRecipeDetailViewModel(settings, logger).AddTo(this.CompositeDisposable)); } if ((methods & Method.Download) != 0) { var rdvm = new RecipeDetailViewModel(settings, logger).AddTo(this.CompositeDisposable); rdvm.IsDownaloding.Subscribe(x => { this.IsBusy.Value = x; }); this.MethodList.Add(rdvm); } if ((methods & Method.HistorySearch) != 0) { this.MethodList.Add(new SearchRecipeViewModel(settings, logger).AddTo(this.CompositeDisposable)); } // 表示コンテンツ切り替わり this.SelectedMethod.Subscribe(vm => { if (vm == null) { this.SelectCommand = new ReactiveProperty <bool>(false).ToReactiveCommand().AddTo(this.CompositeDisposable); return; } this.SelectionResult = this.SelectedMethod.Value.DecidedRecipe.ToReadOnlyReactiveProperty(); this.SelectCommand = new[] { this.SelectionResult.Select(x => x != null), this.IsBusy.Select(x => !x) }.CombineLatestValuesAreAllTrue() .ToReactiveCommand() .AddTo(this.CompositeDisposable); this.SelectCommand.ObserveOnDispatcher(DispatcherPriority.Background).Subscribe(_ => { this.IsBusy.Value = true; // 新規レシピ作成の場合は登録してから終了 if (this.SelectedMethod.Value is RecipeDetailViewModel revm) { revm.DecidedRecipe.Value.RegisterRecipeCommand.Execute(this.Messenger); } this.IsSelectionCompleted.Value = true; this.Messenger.Raise(new WindowActionMessage(WindowAction.Close, "Close")); }).AddTo(this.CompositeDisposable); }).AddTo(this.CompositeDisposable); // Command this.CloseCommand.Subscribe(() => { this.Messenger.Raise(new WindowActionMessage(WindowAction.Close, "Close")); }); // 選択方式変更 this.ChangeMethodCommand.Subscribe(method => { this.SelectedMethod.Value = method; }).AddTo(this.CompositeDisposable); // 選択方式選択に戻る this.CanBack = this.SelectedMethod.Select(x => x != null).ToReadOnlyReactiveProperty().AddTo(this.CompositeDisposable); this.BackCommand = this.CanBack.ToReactiveCommand().AddTo(this.CompositeDisposable); this.BackCommand.Subscribe(() => { this.SelectedMethod.Value = null; }).AddTo(this.CompositeDisposable); }