.NETで作る!

.NETに関するあれこれ(C#、VB.NET)

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.NETWPFアプリケーション作成した際、NuGetから以下をインストールしました。

*1:ビジネスアプリ。グラフィックとかエフェクトとかの需要はほぼない。

*2:手組でMVVMアプリは何本か作成したことがあるので、BindingとかINotifyPropertyChangedとかVとかVMの知識は一応あり。メモリリークとかの対応するもの大変そうなのでメジャーフレームワークに移行。ModelBase、ViewModelBase、Command、ViewModelLocator(画面遷移)、DialogがわかればOK。

*3:VBのサンプルはほぼありません。日本語の初心者向けドキュメントも少なめ。

*4:MVVVM Light Toolkitはサンプルがあまりなく、見つかったのはC#でMessageBoxを使ってたのでナシ。多分違うやり方もあるんでしょうけどきりがないからあきらめました。

. .