WPF版Prismは使いこなすと強力です。でも使いこなすの大変です。ハイ。学習コストかけてられないし、学習コストかけたからといって1個のアプリ開発で、そのコストを回収できるかもわかりませんですしね。 ということで、なるべくライトにPrismを使ってみたいと思います。
Prismで使いたい機能
以下の機能を使おうと思います。
- MVVM基本クラス
- BindableBaseクラス
- DelegateCommandクラス
- ViewModelLocator
- InteractionRequest
- PopupWindowAction
- DIコンテナのUnity
逆に以下の機能は使わない前提です。
- Bootstrapper
- Module
- Region
では行ってみましょう。
プロジェクトの作成
LightweightPrismSampleという名前でプロジェクトを作ったという前提で説明します。NuGetからPrism.Unityをインストールします。
MainWindowは後で作り直すので削除しておきます。
Appクラス
App.xamlからStartupUriを消してStartupメソッドに書き換えます。ここでちょっとUnityの初期化とか書くようにします。
<Application x:Class="LightweightPrismSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LightweightPrismSample" Startup="Application_Startup"> <Application.Resources> </Application.Resources> </Application>
ViewModelLocatorを使うためのおまじないみたいなものです。アプリで管理しているUnityのコンテナからViewModelを生成するようにしています。
using Microsoft.Practices.Unity; using Prism.Mvvm; using System.Windows; namespace LightweightPrismSample { public partial class App : Application { // アプリで管理するコンテナ private IUnityContainer Container { get; } = new UnityContainer(); private void Application_Startup(object sender, StartupEventArgs e) { ViewModelLocationProvider.SetDefaultViewModelFactory(x => this.Container.Resolve(x)); } } }
Viewの作成
Views名前空間にMainWindowを作成します。ViewModelLocatorを使うおまじないをAppクラスでしてるので、ViewModelLocatorが使えます。
<Window x:Class="LightweightPrismSample.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:LightweightPrismSample.Views" xmlns:Prism="http://prismlibrary.com/" Prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d" Title="MainWindow" Height="300" Width="300"> <Grid> </Grid> </Window>
Appクラス再び
MainWindowを表示させます。せっかくなのでUnityから作りましょう(深い意味はない。DIしたければできるようになるっていうくらい)
using Microsoft.Practices.Unity; using Prism.Mvvm; using System.Windows; namespace LightweightPrismSample { public partial class App : Application { // アプリで管理するコンテナ private IUnityContainer Container { get; } = new UnityContainer(); private void Application_Startup(object sender, StartupEventArgs e) { ViewModelLocationProvider.SetDefaultViewModelFactory(x => this.Container.Resolve(x)); this.Container.Resolve<MainWindow>().Show(); } } }
この時点で、MainWindowが表示されるようになります。
ViewModelの作成
では、ViewModelを作成していきます。ViewModels名前空間に以下のようなViewModelを作ります。InteractionRequestやDelegateCommandやBindableBaseを使います。
using Prism.Commands; using Prism.Interactivity.InteractionRequest; using Prism.Mvvm; namespace LightweightPrismSample.ViewModels { public class MainWindowViewModel : BindableBase { public DelegateCommand AlertCommand { get; } public InteractionRequest<INotification> AlertRequest { get; } = new InteractionRequest<INotification>(); private string input; public string Input { get { return this.input; } set { this.SetProperty(ref this.input, value); } } public MainWindowViewModel() { this.AlertCommand = new DelegateCommand(() => this.AlertRequest.Raise(new Notification { Title = "Alert", Content = this.Input })); } } }
Viewの調整
ViewModelに合わせてViewも調整します。InteractionRequestに応答するトリガーや、PopupWindowActionなんかを使っています。Behaviorを使うのでSystem.Windows.Interactionアセンブリを参照に追加するのを忘れずに。
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:LightweightPrismSample.Views" xmlns:Prism="http://prismlibrary.com/" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" x:Class="LightweightPrismSample.Views.MainWindow" Prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d" Title="MainWindow" Height="300" Width="300"> <i:Interaction.Triggers> <Prism:InteractionRequestTrigger SourceObject="{Binding AlertRequest}"> <Prism:PopupWindowAction /> </Prism:InteractionRequestTrigger> </i:Interaction.Triggers> <StackPanel> <TextBox Text="{Binding Input, Mode=TwoWay}" /> <Button Content="Alert" Command="{Binding AlertCommand}" /> </StackPanel> </Window>
実行
実行するとWindowが立ち上がり、TextBoxに入力した内容がボタンを押すとポップアップで表示されます。 画面遷移とかしたかったら自力でファイト!という感じで凝ったことしようとするとPrismの機能が恋しくなるかもしれませんが、そうじゃない軽いアプリならこんな構成もありかなという感じです。
おまけ
今回のプロジェクトはGitHubに公開しています。
このプロジェクトを育てるには
AppクラスのStartupイベントでUnityのコンテナにModelやら必要なクラスの登録処理を書いたり色々やってよしなにやる感じです。