第1回では、ViewとViewModelの対応をアプリの初期化メソッドOnInitializeAsyncで登録しました。
DIコンテナのUnity
App.xaml.cs
namespace PrismApp1
{
public partial class App : PrismApplication
{
...
protected override Task OnInitializeAsync(IActivatedEventArgs args)
{
ViewModelLocationProvider.Register(typeof(MainPage).ToString(), () => new MainPageViewModel(NavigationService));
ViewModelLocationProvider.Register(typeof(UserInputPage).ToString(), () => new UserInputPageViewModel(NavigationService));
return base.OnInitializeAsync(args);
}
}
}
この方法は、画面数が増えてくるとViewとViewModelの対応を維持しづらくなる問題があります。 これを解決するために、依存性を管理するDIコンテナのUnityを使います。
NuGetでパッケージ追加
Prism.Unityパッケージを追加します。
App.xaml、App.xaml.csの修正
App.xaml.csで以下を変更します。
-
PrismUnityApplicationを継承する。
-
OnInitializeAsyncメソッドを削除する。
using Prism.Mvvm;
using Prism.Unity.Windows;
using Prism.Windows;
using PrismApp1.ViewModels;
using PrismApp1.Views;
using System.Threading.Tasks;
using Windows.ApplicationModel.Activation;
namespace PrismApp1
{
public partial class App : PrismUnityApplication
{
public App() : base()
{
InitializeComponent();
}
protected override Task OnLaunchApplicationAsync(LaunchActivatedEventArgs args)
{
NavigationService.Navigate("Main", null);
return Task.FromResult<object>(null);
}
}
}
App.xamlも同様にPrism.Unity.Windows.PrismUnityApplicationを継承します。
<prism:PrismUnityApplication
x:Class="PrismApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PrismApp1"
xmlns:prism="using:Prism.Unity.Windows"
RequestedTheme="Light">
</prism:PrismUnityApplication>
ViewModelはUnityを利用しない場合と同じで、ViewModelBaseを継承して、 コンストラクタの引数でINavigationService navigationServiceを受け取ります。
コードではViewとViewModelの関係を登録していませんが、 実行するとNavigateメソッドで画面遷移することが分かります。
ViewModelLocatorによるViewとViewModelの対応付け
ViewとViewModelの対応付けは
Views/MainPage ⇒ ViewModels/MainPageViewModel
Views/UserInputPage ⇒ ViewModels/UserInputPageViewModel
のように、Navigate("[Name]", …)による画面遷移でViews/[Name]Pageが使用されて、 この画面にViewModels/[Name]PageViewModelが対応づけられます
このViewとViewModelの対応付けはViewModelLocatorによっておこなわれますが、 Views/[Name]PageにおいてViewModelLocatorのAutoWiredViewModel添付プロパティを Trueに設定することで機能します。
MainPage.xaml
<prism:SessionStateAwarePage
x:Class="PrismApp1.Views.MainPage"
...
xmlns:prism="using:Prism.Windows.Mvvm"
...
prism:ViewModelLocator.AutoWireViewModel="True">
...
</prism:SessionStateAwarePage>
このように、Views/[Name]PageとViewModels/[Name]PageViewModelを 対にして作成するだけで画面を増やすことができます。
サンプルコード
今回のサンプルコードは以下にあります。
PrismForUWPSample/02-Unity/02-01-PrismUnityApp