Prism Template Packを使わないでXamarin.FormsソリューションにPrismを適用する



# はじめに

Visual Studio 2019 for MacにはPrism Template Packがないので、自力でXamarin.FormsソリューションにPrismを適用します。

> 2020/1/13更新
> ViewModelクラスに自作のBindableBaseクラスを継承していたが、初期状態ではなにも継承しなくてよいので削除しました。

# ソリューションを新規作成する

Xamarin.Formsの「空白フォームのアプリ」を作成する。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/1ef1cb99-960e-8c57-aa7b-dda644c6668e.png)

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/7b89e4ae-01a0-8c2a-ed87-ee3eb8a2a882.png)

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/2e630d2a-a58e-0aca-7fa2-04dbbf1977b4.png)

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/adc70318-da9c-769a-3108-82ca3e4688c8.png)

# NuGetでPrism.Unity.Formsを追加する

ソリューションを右クリックして「Manage Nuget Packages...」をクリック。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/3a94bd5c-6663-d9f7-1d97-b1abbd5cb2ec.png)

「Prism.Unity.Forms」を選択して「パッケージを追加」ボタンをクリック。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/51578aa8-9561-ef00-fb0a-ff93e9ccb139.png)

すべてのプロジェクトに追加する。
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/036a7e8a-842a-209b-ef71-d9e4b8040432.png)


# プロジェクトをPrism構成にする

## フォルダ構成の変更
PCLプロジェクトに「Views」「ViewModels」フォルダを追加する。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/60e5aac7-8b80-a95b-b446-72abf7e48faa.png)

MainPage.xaml、MainPage.xaml.csをViewsフォルダに移動する。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/04f779b8-cc8c-e93e-c148-607f3766d0f2.png)

## MainPage.xamlおよびMainPage.xaml.csの名前空間変更

Viewsフォルダに移動したので、名前空間もあわせて変更する。

```C#:MainPage.xaml.cs
// NewPrismApp　から NewPrismApp.Views に変更。
namespace NewPrismApp.Views

public partial class MainPage : ContentPage
{
    // 略
}
```

MainPage.xamlは、ContentPage要素の`ｘ：Class`属性値を
`x:Class="NewPrismApp.MainPage"` から
`x:Class="NewPrismApp.Views.MainPage"` に変更する。

```XML:MainPage.xaml
<?xml version="1.0" encoding="utf-8"?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Class="NewPrismApp.Views.MainPage"> <!-- ←ここを変更。 -->

  <!-- 略 -->

</ContentPage>
```

## 必要なクラスを追加

### MainPageViewModelクラス

ViewModelsフォルダにMainPageViewModelクラスを追加する。
これが、MainPageのViewModelクラスとなる。

```C#:MainPageViewModel.cs
namespace NewPrismApp.ViewModels
{
    public class MainPageViewModel
    {
        public MainPageViewModel()
        {
        }
    }
}
```

## App.xaml、App.xaml.csをPrism構成にする

### App.xaml
Applicationタグをprism:PrismApplicationに書き換え、以下のprism名前空間を追加する。
`xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"`


```XML:App.xaml
<?xml version="1.0" encoding="utf-8"?>
<prism:PrismApplication
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
    mc:Ignorable="d"
    x:Class="NewPrismApp.App">

    <Application.Resources>
    </Application.Resources>

</prism:PrismApplication>
```

### App.xaml.cs
以下の内容に書き換える。
インテリセンスでエラーが表示されるので、ヒントでusingを追加したり、たまにビルドするとエラーを解決できます。

```C#:App.xaml.cs
using NewPrismApp.ViewModels;
using Prism;
using Prism.Ioc;
using Xamarin.Forms;

namespace NewPrismApp
{
    public partial class App
    {
        public App()
        {
            InitializeComponent();
        }

        public App(IPlatformInitializer platformInitializer) : base(platformInitializer)
        {

        }

        protected override void OnInitialized()
        {
            InitializeComponent();

            // 起動直後にMainPageを表示する。
            NavigationService.NavigateAsync("NavigationPage/MainPage");
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();

            // View「MainPage」ViewModels「MainPageViewModel」を登録する。
            containerRegistry.RegisterForNavigation<MainPage, MainPageViewModel>();
        }
    }
}
```

# 動作確認

エミュレータで実行すると動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/70a9a031-d573-ddd0-421c-539e22a54e89.png)

# トラブルシューティング

## MainPageが表示されず、真っ白の画面になる。

Visual Studio for Macのソリューションエクスプローラ上でMainPage.xamlをドラッグアンドドロップして別のフォルダに移動すると、一見MainPage.xaml.csも一緒に移動してくれているように見えますが、ソリューションからMainPage.xaml.csが外れてしまうことがあります。

Visual Studio for Macをいったん終了し、.vsフォルダ（隠しフォルダ）を削除してからソリューションを起動するとソリューションエクスプローラからMainPage.xaml.csがなくなっていると思います。
改めてソリューションに追加してあげれば、MainPageが表示されるようになります。