レガシーコードからの脱却

レガシーな職場でも独学でどうにか頑張っていくブログです。

【お勉強記録】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に関してもう一度学び直して、しっかり理解した方がいいと感じたので、並行してお勉強します。

MaterialDesignInXamlToolkit でデザインかっこよくできました。

MaterialDesignInXamlToolkit

Windowsのデスクトップアプリを作成してみて思っていたこと…それは出来上がったもののデザインがくそダサいということ。

WPFでBootstarp的なものとかないのかなぁと調べてみたところ、MaterialDesignInXamlToolkitとかいうライブラリのQiitaの記事がありました。 とても参考になりました。ありがとうございます。

Material Design In XAML ToolkitでWPFアプリにモダンなUIを! - Qiita

というわけで、前回作ってみたTodoアプリにさっそく導入してみました。

写真は日付を選ぶところです。

f:id:Gappory:20170910172038p:plain

ちょちょっと数行書くだけで、いろいろ格好良くしてくれました。 画像ではわかりませんが、マウスが当たった際のアニメーションなんかも良いです。 上の記事でも書かれてる通り、Gitからデモアプリを落として、実行してみるとどんなことができるのかすぐにわかります。

人のソース読むの大事

デモアプリについて、ライブラリでできることの多さに感動することもそうなんですが、WPFでここまでかっこいいものが作れるのかと感動しています。 また、こういったデザインを適応するのに適したXAMLの書き方もあるよなぁとおぼろげながら思いました。 MVVM系のライブラリを色々検討している際にも思ったのですが、やっぱり公開されているソースを読むのってかなりお勉強になるなと感じています。

最後に

Visual Studio2017を入れるのにめちゃくちゃ時間と容量を食ってしまいました。 MVVMのライブラリはPrismを勉強していくことに決めました。会社の先輩に相談したところ、Prismを使っているとのことだったので、わからないこと聞きやすいなと思ったのが決め手です。