WPF+Prism 5.0 でMVVMアプリを作る(前準備)
前段
WPFのMVVMフレームワークといえばPrismとMVVM Light Toolkitがメジャーどころです。
新規に始める場合、「どちらを学べばよいか」という非常に悩ましい問題があります。 しかし初学者が適切に選べるわけもないので、自分のやりたいこと*1、わからないこと*2の情報があったという理由で Prism(Prism.Mvvm)を選びました。
patterns & practices: Prism - Downloads
結局のところ、使い方がわからなければどうにもならないですしね。*3
Prism.Mvvm
他者様のサイトを引用します。
•Prism.Mvvm
MVVMをするための基本的なICommandの実装やINotifyPropertyChangedの実装の他にViewとViewModelを自動的に結び付ける機能を提供します。
よりMVVMに、よりライトにPrism 5がリリースされました - かずきのBlog@hatena
PrismはMicrosoftのpatterns & practicesで開発された複合アプリケーションを作成するためのフレームワークです。そのためもともとMVVMをサポートするためのライブラリというよりモジュールを組み合わせて1つのアプリケーションを作成するというタイプのアプリケーションを作るためのフレームワークとして開発されていました。今回のバージョン4から、MVVMをサポートするクラスがいくつか追加されています。
MVVM入門 その4「ライブラリを使おう」 in C# for Visual Studio 2010
両方とも同じ著者さんですが、特に下段リンク先にある主要クラスの一覧と説明はとても参考になりました。
参考サイト
参考にした際は以下の通り。
Dialog
Nortification(OK Only),Confirmation(OK or Cancel)、Custom Dialog、Item Selection Popup
Interactivity Code Sample using the Prism Library 5.0 for WPF in C# for Visual Studio 2013
このサンプルはPrismを選ぶ決め手になりました。*4
DelegateCommand(ICommand、WeakReference)
CommandのCanExecuteが初回しかコールされなかった場合の対応(DelegateCommandのCanExeuteとCommandManager.RequerySuggestedの紐づけ。
patterns & practices: Prism - DelegateCommand<T> & CanExecute delegate...
ViewModelLocator
「Modern UI for WPF」の「MVVM Light Toolkit」のサンプルコードとか「UnityContainer に登録したインスタンスを取り出す - present」とかをあさって、最終的にUnityを使うこととしました。
patterns & practices - Unity - Home
いろいろすっ飛ばすと、最終的にこのコードで実装。
Imports Microsoft.Practices.Unity Imports Microsoft.Practices.ServiceLocation ''' <summary> ''' ロケーター ''' </summary> ''' <remarks> ''' View(XAML)からDataContext(ViewModel)を取得するためのアクセッサ。 ''' Application.xamlにてリソースとしてインスタンスして使用します。 ''' <code>local:ViewModelLocator x:Key="Locator"</code> ''' </remarks> Public Class ViewModelLocator Public Sub New() Dim container As New UnityContainer Dim service As New UnityServiceLocator(container) ServiceLocator.SetLocatorProvider(Function() service) container.RegisterInstance(Of LoginViewModel)(New LoginViewModel) End Sub ''' <summary> ''' ログインViewModel ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks> ''' バインディングするため、プロパティ化する必要あり。 ''' <example>DataContext="{Binding LoginViewModel, Source={StaticResource Locator}}"</example> ''' </remarks> Public ReadOnly Property LoginViewModel Get Return ServiceLocator.Current.GetInstance(Of LoginViewModel)() End Get End Property Public Shared Sub Cleanup() 'TODO:Cleanup End Sub End Class
<Application x:Class="Application" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PrismMvvmApplication" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <local:ViewModelLocator x:Key="Locator" /> </ResourceDictionary> </Application.Resources> </Application>
<UserControl x:Class="LoginView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:prism="http://www.codeplex.com/prism" mc:Ignorable="d" xmlns:local="clr-namespace:PrismMvvmApplication" d:DesignHeight="300" d:DesignWidth="600" DataContext="{Binding LoginViewModel, Source={StaticResource Locator}}"> <Grid> <!--略--> </Grid> </UserControl>
参照したライブラリ
.NET4.5.1+VS2013+VB.NETでWPFアプリケーション作成した際、NuGetから以下をインストールしました。
- Prism.Interactivity MVVMフレームワーク
- Prism.Mvvm MVVMフレームワーク
- CommonServeiceLocator 画面遷移用途してインポート
- Unity 画面遷移用途してインポート
*1:ビジネスアプリ。グラフィックとかエフェクトとかの需要はほぼない。
*2:手組でMVVMアプリは何本か作成したことがあるので、BindingとかINotifyPropertyChangedとかVとかVMの知識は一応あり。メモリリークとかの対応するもの大変そうなのでメジャーフレームワークに移行。ModelBase、ViewModelBase、Command、ViewModelLocator(画面遷移)、DialogがわかればOK。
*3:VBのサンプルはほぼありません。日本語の初心者向けドキュメントも少なめ。
*4:MVVVM Light Toolkitはサンプルがあまりなく、見つかったのはC#でMessageBoxを使ってたのでナシ。多分違うやり方もあるんでしょうけどきりがないからあきらめました。