Caliburn.Microを用いてWPFアプリケーションを作成する(1)

# Caliburn.MicroでWPFアプリが空ウィンドウで開くまでを作成する。

## 序

MVVMをマイルドにしてくれるフレームワークCaliburn.Microの紹介動画をもとに、だいたいの使い方を追体験してみる。

ソリューションの作成～空ウィンドウを表示するところまでをやってみる。


### 雑文

<details>
c#初心者でもあるワイ君が2020年にもなってWPFに入門しようとしたが、どこから手をつけていいのか迷いつつQiita等をみていた。
[むずかしくないWPF](https://qiita.com/karno/items/f30f661b40d9adec6a6d) を見ると、WPFはMVVMパターンで構築するのが筋で、WinFormsのときのように 'コントロール.Text="はにゃーん"' のように直接ビューを操作するのは禁じ手らしい。
XAMLというXML派生言語（ビルド時にC#コード生成されるらしい）で外観設定して、ViewModelを介して描画やイベント処理するとのことで、そのあたりの作法をマイルドにするフレームワークがいくつかあるらしい。ふむふむ。WebとかVue.jsでいうとdata()を、computed()で表示するとかそういうかんじ？と雑な考えのもと、調査。

MVVMまわりを楽にしてくれるフレームワークは色々あって迷った。
ググるとLivetなんかが日本初で歴史もあってよさそうな雰囲気だったけど、現在はほぼメンテナンスモードで.Net Core追従等の維持はされつつも新機能追加はしない方向性のようだった。
後発らしい Caliburn.Micro はどうだ？と思ったら、Qiitaに記事は少ないけど、YouTubeで使い方をレクチャしてくれるおじさんがいたので、そちらをなぞってみることにした。
</details>

### 前提環境

* Windows10
* VisualStudio2019 Community
* .NET framework 4.7.2
* Caliburn.Micro 3.2.0 (NuGetでインストール)

## 参考にする動画

*  [WPF in C# with MVVM using Caliburn Micro](https://www.youtube.com/watch?v=laPFq3Fhs8k) 


## 初期準備

動画のTimおじさんに従ってデモスタート。

### 新しいプロジェクトの作成
「新規作成」→「プロジェクト」で「WPFアプリ (.NET Framework)」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/44757962-d342-0442-606c-e14d8fb92ea3.png)
チュートリアルということでプロジェクト名は「WOFtut01」とした。

### NuGetによるライブラリ導入
ソリューションエクスプローラで右クリックするメニューから「NuGetパッケージの管理」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/a3ab8119-024f-0438-7657-4bee29f7e7bb.png)
参照から「Caliburn.Micro」（途中までタイピングすると2020年6月時点では3.2.0が候補ででてくるはず）を選択し、「インストール」する。

### 不要ファイルの削除
MainWindows.xamlを削除する。

### App.xamlの編集。
削除したファイルの記述　StartupUri="MainWindow.xaml　を除去し、かわりに描画を担当する部分の記述を追加する。
動画を参考に直接編集する。xamlのタグは途中までタイプすると補完候補がでてくる。

```xml:App.xamlのApplicationタグ内に追加
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:Bootstrapper x:Key="Bootstrapper"/>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
```
### Bootstrapperクラスの追加

* 上記App.xamlで設定したBootstrapper用クラスファイルを作成する。

ソリューションエクスプローラで「追加」→「クラス」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/30c4de82-99a9-7258-1445-f2306c504fca.png)

名前を「Bootstrapper.cs」とする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/90cb8336-dabd-e1d8-6a1a-0896a33b4b3e.png)


* Bootstrapper.csを編集。

publicにして、BootstapperBaseを継承。継承させる部分をタイプしたところでVS2019が警告と提案をだしてくれるので、提案を受け入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/1ab05b23-3503-525e-595c-1ff0f846b54c.png)
→自動的に using が入力される

続いてコンストラクタを作る。中身は Initialize();のみ。
つづいてStartup用関数を作成する。
'ctor'とタイプしてタブを2回押すとsnippet展開される。

```cs:Bootstrapper.csの一部
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            base.OnStartup(sender, e);
        }
```

動画のとおりにOnStartupを書き換える。

```cs
        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            // base.OnStartup(sender, e);
            DisplayRootViewFor<ShellViewModel>(); //←後半でエラーとなる警告がでるが、そのまま（後述）
        }
```

DisplayRootViewFor部分が、削除したMainView.xamlの代わりになる部分。

### MVVM用のフォルダを作成する。

ソリューションエクスプローラで Models, Views, ViewModels の3フォルダを「新しいフォルダー」で追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/51881cf3-aac6-ce47-5ec0-b2b2b47a62b6.png)

### 表示のもとになるViewModelを追加する

ソリューションエクスプローラのViewModelsに、Bootstrapを作成したとき同様にクラス（ファイル）を追加。
ファイル名はShellViewModel.csとする（後述：命名規則が重要、ここではShellという内容のViewModelを表すとおもっておけばよい）
生成されたファイルは次の内容に修正する（publicにして、Screenを継承）

```cs:ShellModelView.cs
using Caliburn.Micro;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WPFtut01.ViewModels
{
    public class ShellViewModel : Screen
    {
    }
}
```

### 表示用のViewを追加する

ソリューションエクスプローラでViews下で、「追加」→「ウィンドウ(WPF)」を選択。
空のウィンドウが作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/29cd782c-d579-da68-0877-82d678b3f004.png)

### 実行してエラーがでることを確認する

ウィンドウが出来たので、いざ実行！とすると次のようにエラーがでる。

```
重大度レベル	コード	説明	プロジェクト
エラー	CS0246	型または名前空間の名前 'StartupEventArgs' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)。	WPFtut01
エラー	XDG0008	名前 "Bootstrapper" は名前空間 "clr-namespace:WPFtut01" に存在しません。	WPFtut01
エラー	XDG0008	名前 "Bootstrapper" は名前空間 "clr-namespace:WPFtut01" に存在しません。	WPFtut01
```

この時点で、Bootstrapper.csを開くと、<ShellViewModel>() 部分に警告がでているままになっている。
Usingが不足しているので、次の2行を追加する（本記事の例ではnamespace がWPFtut01だが、途中までタイプすると補完され、ピリオドをうつと更に補完候補がでてくるので ViewModelsを追加する）

```cs:Bootstrap.cs
using System.Windows;
using WPFtut01.ViewModels;
```

これでエラーが消え、実行すると空のShellViewが表示できるようになった。

### ShellView.xamlを編集し、Backgroundの色を変えてみる

正しくShellViewがよばれてることを実感する

## まとめ

動画ではこのあたりウィンドウ表示のあたりで、命名規則について概説してくれる。
Caliburn.MicroではRoR等のCoCのように名前に基づいた紐づけが行われる（らしい）。
（ex: 'ほにゃViewModel.cs'に対し、'ほにゃView.xaml'）

* 次の記事： [Caliburn.Microを用いてWPFアプリケーションを作成する(2)](https://qiita.com/paichi81@github/items/32bc798536ac8c1b35a5)