search
LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

Xamarin.FormsとPrismとWPFとStoryboard

この記事は Xamarin Advent Calendar 2020 の7日目の記事です。

登場人物たち

Prism

いろいろ入ってるライブラリ集みたいな認識です。
個人的にはDI(Unity)とPubsubとViewModelシステムを使っています。
スタートアップはこの記事で。

WPF

いまさらWPFかい、とか言わないでください。
弊社ではWindows8.1が現役で使われてたりします。
(早く撲滅してください…)

Storyboard

MacのStoryboardです。
ここんとこ書くなら毎回この記事です。

基本

皆さん、もう.NET5へ移行しますよね?してますよね?
自分はそちらで。
というわけで、テスト用のソリューションを作ります。

$ mkdir XamarinTest
$ cd XamarinTest
$ dotnet new sln

そして、共通で使うライブラリプロジェクトを作ってしまいましょう。

$ dotnet new classlib -n XamarinTestCommon
$ dotnet add XamarinTestCommon/XamarinTestCommon.csproj package Prism.Core
$ dotnet sln add XamarinTestCommon/XamarinTestCommon.csproj

何はなくともPrism
最近はXamarin.FormsよりPrism必須です。
あと、Windows TerminalでGit Bashです。

Xamarin.FormsとWPF

WPF用のXamarin.Formsは .Net Framework用しかありません
Xamarin.Formsの中で使われてるOpenGL用のライブラリ、OpenTK.GLControlが.Net Framework用しかないからです。

つまり、 .NET5を使うならXamarinは使わない ということになります。

プロジェクト作成

$ dotnet new wpf -n XamarinTest.wpf
$ dotnet add XamarinTest.wpf/XamarinTest.wpf.csproj reference XamarinTestCommon/XamarinTestCommon.csproj
$ dotnet add XamarinTest.wpf/XamarinTest.wpf.csproj package Prism.Unity
$ dotnet sln add XamarinTest.wpf/XamarinTest.wpf.csproj

何はなくともPrism。
そして使わないXamarin。

WPF結論

.NET5を念頭に置くならXamarin.Formsは入る余地なし なのです。
Xamarin.FormsをWPFで使うなら.Net Frameworkを使いましょう。
(もしくはMAUIを待つか、OpenTK.GLControlが.NET5に対応するのを待つか…)

Xamarin.FormsとStoryboard

macOSでXamarin.Formsを使いつつ、Storyboardも使ってプログラムを作ります。

プロジェクト作成

先ほどのソリューションを使いまわしましょう。

$ open XamarinTest.sln

何はなくともPrism。
Cocoaプロジェクトを作り、NuGetからPrism.Unity.Formsを追加します。
image.png

Storyboardの設定を変更する

次にMain.storyboardをXcodeで開き、以下を設定します。
設定する項目は

  • Window Controlleris initial controllerのチェックを外す
    image.png

  • Window ControllerStoryboard IDを設定する
    image.png

です。

AppDelegateを変更する

AppDelegateを以下に変更します。

using AppKit;
using Foundation;
using Prism.Ioc;
using Prism.Unity;

namespace XamarinTest.mac
{
    [Register("AppDelegate")]
    public class AppDelegate : Xamarin.Forms.Platform.MacOS.FormsApplicationDelegate
    {
        // ** 1. **
        public override NSWindow MainWindow => MainWindowController.Window;
        public NSWindowController MainWindowController { get; }
        public CoreApp CoreApp { get; private set; }

        public AppDelegate()
        {
            // ** 2. **
            MainWindowController = NSStoryboard.MainStoryboard.InstantiateControllerWithIdentifier("MainWindowController") as NSWindowController;
            MainWindow.MakeKeyAndOrderFront(this);
        }

        public override void DidFinishLaunching(NSNotification notification)
        {
            // ** 3. **
            Xamarin.Forms.Forms.Init();
            LoadApplication((CoreApp = new CoreApp()));
        }
    }

    public class CoreApp : PrismApplication
    {
        protected override void OnInitialized()
        {
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
        }
    }
}

やってることは、
1. Window関連のプロパティを設定する
2. StoryboardからWindow Controllerを読み出し、Windowを作成する
3. Xamarin.Formsを初期化する

CoreAppクラス内でMainPageを初期化していないので、Xamarin.FormsのPageは作られません。
その上でApplicationをPrismApplicationで作ることでPrismを使用するようにします。

Storyboard結論

こうなってしまうとViewModelは使えないので、Xamarin.Formsの利点がなくなり、Prismを使うためだけの土管になります。
すなおにViewControllerを捨て、CoreAppコンストラクタ内でMainPageを設定しましょう。

MAUIはよはよ!

使わなかったり土管だったりでPrism↑↑Xamarin.Forms↓↓な記事になってしまいましたが。
MAUIが出る頃には状況が変わるでしょうか。
RendererがXamarin.Forms.Platformだったりしてまだまだな感じのMAUIですが、このままフツーに乗り換えできそう。
楽しみです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2