質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

9056閲覧

【C#】【WPF】PrismのRequestNavigateを使用してスクロールするような遷移がしたい

OXamarin

総合スコア59

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MVVM

MVVM(Model View ViewModel)は構築上のデザインパターンで、表現ロジック(ViewModel)によってデータ(Model)からページ(View)を分離させます。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

1クリップ

投稿2019/07/15 11:54

##前提
環境:VS2019
WPFでPrism 7.1 を使用してMVVMに則ったプログラムを作成しています。
DIコンテナにはUnityを使用しています。

##悩んでいる事
表題の通りです。
幾つかのページがあり、ページを切り替える際にスクロールするような遷移がしたいです。
RegionNameにViewModelの名称を代入するだけでページ遷移ができるようになってしまったせいでページ遷移の方向が割り当てられなくなってしまいました。

どの方向に遷移させるのかを動的に決められるようにもしたいです。

##具体例
「スクロールするような遷移」とは以下のようなものです。
イメージ説明

UserControlで作成された4つのViewがあり、各ボタンに対応したViewの切り替えをするようにしていました。
この画面遷移の方法については、以下のソースを流用しています。
WPF で画面遷移のアニメーションをするためのステップ 4

画面の切り替えと遷移の方向についてはViewModelからMainWindow.xamlへバインディングを行い、遷移のアニメーションについてはバインドされた値に応じて予め定義しているStoryBoardを実行するようにしています。

C#

1<!--メニュー選択時に差し変わるメイン画面--> 2<ContentControl Grid.Column="1" Grid.Row="1" 3 Content="{Binding CurrentViewModel}" 4 ContentTemplate="{Binding TransitionDirection, Converter={StaticResource transitionConverter}}"> 5</ContentControl>

###上記の実装だとダメな理由
上記の方法だと

  1. MainのViewModel内で遷移先のViewModelを生成しており、引数を増やした場合に辛くなる
  2. ViewとViewModelの紐づきをResource内に持っており、非常に分かり辛い
  3. (組み方が悪いのだと思いますが)DIコンテナを使用するとページ遷移時に毎回ViewModelのインスタンス生成が走ってしまい、パフォーマンスが落ちるだけでなく前回入力した情報が保持されない

という状態に陥っています。

###ページの切り替えの代替案としてPrismのRequestNavigateを使う
ダメな理由の3番目が特に致命的なので、別の方法でページ遷移させることにしました。

そもそもPrismを使用していたのでPrism周りで探して以下のサイトを参考にさせて頂きました。
WPF Prism episode: 4.5 ~ ReactiveProperty からはじまる MVVM 狂想曲 ~

元々ではMainWindow.xmlのCurrentViewModelに遷移先のViewModelを、TransitionDirectionに遷移方法をバインドしていましたがRequestNavigateを使えば遷移先の名称をRegionNameに対してセットしてあげるだけで遷移できます。

C#

1<!--メニュー選択時に差し変わるメイン画面--> 2<ContentControl x:Name="PartialViewArea" Grid.Column="1" Grid.Row="1" 3 prism:RegionManager.RegionName="PartialViewArea" />

ViewModel側でRequestNavigateを実行するのみでよい。

C#

1/// <summary> 2/// 画面遷移 3/// </summary> 4private void OnScreenChanged() 5{ 6 if (_selectedMenu == null) return; 7 8 // ViewModel の切り替え 9 _regionManager.RequestNavigate("PartialViewArea", _selectedMenu.MenuName); 10}

結果、現状では以下のようになっています。
イメージ説明

RequestNavigateを使用して、ページが切り替わる度にViewModelが再生成される事はなくなりましたが、RegionNameにViewModelの名称を代入するだけでページ遷移ができるようになってしまったせいでページ遷移の方向が割り当てられなくなってしまいました。

##他に調べた事
バインドができないならと、UserControl表示時にTriggerを使ってスライドさせてみました。

C#

1<UserControl.Triggers> 2 <EventTrigger RoutedEvent="Control.Loaded"> 3 <BeginStoryboard> 4 <Storyboard > 5 <ThicknessAnimation Duration="0:0:.8" Storyboard.TargetProperty="Margin" From="1920,0,0,0" To="0" AccelerationRatio=".1"/> 6 </Storyboard> 7 </BeginStoryboard> 8 </EventTrigger> 9</UserControl.Triggers>

以下の様になります。
イメージ説明

ただこれだと、一番最初のGifのように前画面からの遷移ぽくないので、前画面が少しずつ幅が狭くなっていくような遷移があれば知りたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。

元から、以下の様にできていたのですから、

xaml

1<!--メニュー選択時に差し変わるメイン画面--> 2<ContentControl Grid.Column="1" Grid.Row="1" 3 Content="{Binding CurrentViewModel}" 4 ContentTemplate="{Binding TransitionDirection, 5 Converter={StaticResource transitionConverter}}"> 6</ContentControl>

ContentをRegionNameにかえてやるだけで済む話でした。

C#

1<!--メニュー選択時に差し変わるメイン画面--> 2<ContentControl Grid.Column="1" Grid.Row="1" 3 prism:RegionManager.RegionName="PartialViewArea" 4 ContentTemplate="{Binding TransitionDirection, 5 Converter={StaticResource transitionConverter}}" 6 />

投稿2019/07/16 12:46

OXamarin

総合スコア59

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問