##前提
環境: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>
###上記の実装だとダメな理由
上記の方法だと
- MainのViewModel内で遷移先のViewModelを生成しており、引数を増やした場合に辛くなる
- ViewとViewModelの紐づきをResource内に持っており、非常に分かり辛い
- (組み方が悪いのだと思いますが)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のように前画面からの遷移ぽくないので、前画面が少しずつ幅が狭くなっていくような遷移があれば知りたいです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。