Prism自習 2 (了)
MVVMの基本クラス
Prismで提供されるMVVMの基本クラスに関してです。
BindableBase
INotifyPropertyChangedの実装クラスで、プロパティのsetメソッドでSetProperty(ref フィールドネーム, value)とすることで、PropertyChangeイベントを発行してくれます。
DelegateCommand
Commandの実装クラスはDelegateCommandです。コンストラクタの第1引数にExecute時に実行される処理を、第2に引数にCanExecute時の処理を渡して使用します。
ObservePropertyメソッドを使うことで、プロパティの変更を監視し、変更時にCanExecuteChangedを発生させることができるようです。すごい...
InteractionRequest
PrismではInteractionRequestクラスを用いてダイアログを実装するようです。 OKボタンなど普通のダイアログを出すNotificationクラス、Yes/No付きのダイアログを出すConfirmationクラスがあり、Notificationを拡張することで、独自のダイアログを実装することも可能なようです。 (Confirmationも実際には、Notificationの拡張クラスのようです。)
型引数にNotificationを指定したInteractionRequestクラスのプロパティを定義して、CommandにRaiseイベントを実装したメソッドを指定することで使用できます。
//InteractionRequestクラスのプロパティ public InteractionRequest<Notification> NotificationRequest { get; } = new InteractionRequest<Notification>(); public DelegateCommand NotificationCommand { get; } //コンストラクタでDelegateCommand にNotificationCommandExecuteメソッドを指定 public InteractionRequestViewModel() { this.NotificationCommand = new DelegateCommand(this.NotificationCommandExecute); } //Raiseイベントの実装 private void NotificationCommandExecute() { this.NotificationRequest.Raise(new Notification { Title = "Alert", Content = "Notification message." }); }
<prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest, Mode=OneWay}"> <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True"> <prism:PopupWindowAction.WindowStyle> <Style TargetType="Window"> <Setter Property="ResizeMode" Value="NoResize" /> <Setter Property="SizeToContent" Value="WidthAndHeight" /> </Style> </prism:PopupWindowAction.WindowStyle> </prism:PopupWindowAction> </prism:InteractionRequestTrigger>
ナビゲーション
ビュー切り替え時のナビゲーションには、PrismではPrism.Regions.INavigationAwareを用います。
// // 概要: // Provides a way for objects involved in navigation to be notified of navigation // activities. public interface INavigationAware { // // 概要: // Called to determine if this instance can handle the navigation request. // // パラメーター: // navigationContext: // The navigation context. // // 戻り値: // true if this instance accepts the navigation request; otherwise, false. bool IsNavigationTarget(NavigationContext navigationContext); // // 概要: // Called when the implementer is being navigated away from. // // パラメーター: // navigationContext: // The navigation context. void OnNavigatedFrom(NavigationContext navigationContext); // // 概要: // Called when the implementer has been navigated to. // // パラメーター: // navigationContext: // The navigation context. void OnNavigatedTo(NavigationContext navigationContext); }
OnNavigatedFromメソッドでは画面から離れる際の処理を、OnNavigatedToでは遷移されたときに行われる処理をそれぞれ実装します。 IsNavigationTargetメソッドでは、インスタンスがナビゲーションの要求で処理可能か返します。trueを返すときインスタンスは再利用され、falseの売位は新たなインスタンスが生成されるようです。
ナビゲーションする側はRegionManagerのRecordNavigationメソッドで管理します。NavigatetionParametersクラスを用いればパラメータを渡すことも可能です。 例では、ここでIDを渡すことで、Viewの使いまわしを管理していました。
一通り、Prism自習のコンテンツは消化しましたが、まだ完全理解には程遠いのが現状です。 あとは使いながら覚えていくしかないのですが、なに作ろうかと考えています。 また、ASP.Net MVCで作りたいものが出てきたので、そちらに少し関心が移っています。(ピンチ!) まだ、ある程度は触り続けていないと、知識が0に戻る時期にいるので、0はまずいです。
本当はASP.Net MVCでサービス作って、WPFやXamarinを使ってそれをアプリケーションからも触れるようにするのが最高なのですが、きつすぎ無理っす。
【お勉強記録】Prism6.0の自習(Bootstrapper ViewModelLocater Model Regionまで)
Prism
連休中ということで、Prism6.0を勉強してみました。
かずきさんのPrism自習用リポジトリをもとに勉強しています。
GitHub - runceel/PrismEdu: PrismLibrary japanese text.
Bootstrapper
PrismではShellという基本となる画面があってBootStrapperというUnityBootstrapperを継承したクラスで起動を管理するようです。
using HelloWorldApp.Views; using Microsoft.Practices.Unity; using Prism.Unity; using System.Windows; namespace HelloWorldApp { class Bootstrapper:UnityBootstrapper { protected override DependencyObject CreateShell() { return this.Container.Resolve<Shell>(); } protected override void InitializeShell() { ((Window)this.Shell).Show(); } } }
ViewModelLocater
ViewModelLocaterはViewとViewModelとの紐づけのための機能です。 View(Xaml)のWindowやUserControlに
xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True"
と書くことで、命名のルールに基づいてViewのDataContextにViewModelが割り当てられます。(View:Views.Hoge ViewModel:ViewModels.HogeViewModel といった感じ)
ModuleとRegion
Moduleでアプリケーションの機能ごとに分割して開発することが可能。 Regionは作成されたModuleをShellの特定の領域(Region)に流し込むための機能のようです。Regionのおかげで複数のModuleを柔軟に組み合わせて作ることができるようです。
Moduleで作成する画面部品は「Window」ではなく、「UserControl」ですね。当たり前ですが、ここで少しハマりました。WindowだとShell上でRegionをしっかり定義していても、反映されませんでした。 あとは普通の画面の作成と同じようにModel、View、ViewModelと作っていきます。 それができたら、IModuleインターフェースを実装したクラスを作成します。
using Microsoft.Practices.Unity; using ModuleApp.HelloWorldModule.Models; using ModuleApp.HelloWorldModule.Views; using Prism.Modularity; using Prism.Regions; namespace ModuleApp.HelloWorldModule { public class HelloWorldModule:IModule { [Dependency] public IUnityContainer Container { get; set; } [Dependency] public IRegionManager RegionManager { get; set; } public void Initialize() { this.Container.RegisterType<MessageProvider>(new ContainerControlledLifetimeManager()); this.Container.RegisterType<object, HelloWorldView>(nameof(HelloWorldView)); this.RegionManager.RequestNavigate("MainRegion", nameof(HelloWorldView)); } } }
Containerにクラスを登録するのと、Shellで定義したRegionに画面部品を流し込むためRegionManager.RequestNavigateを実装しました。
本体側では、ModuleをBootstrapperで組み込み、ShellでRegionを定義します。 BootstrapperクラスのConfigureModuleCatalogメソッドをオーバーライドしてModuleを追加するそうです。
protected override void ConfigureModuleCatalog() { base.ConfigureModuleCatalog(); var catalog = (ModuleCatalog)this.ModuleCatalog; catalog.AddModule(typeof(HelloWorldModule.HelloWorldModule)); }
ShellでのRegionの定義方法は以下の通りです。
<ContentControl prism:RegionManager.RegionName="MainRegion" />
これから
今日はPrism自習の先のコンテンツをどんどん進めていきます。 また、DIに関してもう一度学び直して、しっかり理解した方がいいと感じたので、並行してお勉強します。