KENTEM TechBlog

建設業のDXを実現するKENTEMの技術ブログです。

.NET MAUI でアプリを作ろう(基礎編)

こんにちは!KENTEM第2開発部のK.H.です。

1年半ほど前にMAUIでアプリ開発を行う機会があり、その流れでMAUIの記事を書かせていただきました。
その際は苦しかった思い出が強く、MAUIに対する恨みから、ちょっと否定的に書いてしまいました。
ただ、そこから時を経て、恨みの記憶が薄まり、MAUI自体も.NET7⇒.NET8⇒.NET9という進化の中で一番の問題であった不安定さやパフォーマンスが改善されてきたことで、MAUIと仲直りしました。
ということで、MAUI開発者が増えることを祈って、MAUIで実際にアプリを作成する記事を書きたいと思います。
※VisualStudio2022を利用します。

MAUIとは

マウイ島じゃありません!!(昔は検索すると最初に出てきてたんです)
正式名称は .NET MAUI(Multi-platform App UI) です。この記事内ではMAUIに省略させていただきます。
MAUIはMicrosoftが提供するクロスプラットフォームフレームワークです。 一つの実装コードからAndroid、iOS、macOS、Windowsで実行できるアプリを開発できます。
ビジネスロジック部分はC#、UIはXAMLというXMLベースのマークアップ言語で記述します。また、部分的に各プラットフォームごとに拡張処理を記述することも可能です。

アプリ作成

では早速アプリの作成に移っていきましょう。
VisualStudioを起動して、テンプレートの検索欄に「maui」と入れてMAUIプロジェクトを選択してください。

プロジェクト名の設定とフレームワークの選択して作成してください。(今回はフレームワークを.NET 9.0にします)
これで、基本構成は自動的に作成されます。
軽くソリューション構成を説明します。

①App.xaml

MAUIアプリのエントリーポイント。
xamlではあるものの、UIの定義はなし。
アプリ全体に及ぼす設定やアプリの起動やスリープ等のイベントをハンドリングできます。
初期状態では画面クラスとして②のAppShellクラスが指定されています。

②AppShell.xaml

サイドメニュー機能の付いた、画面管理クラスです。
サイドメニューの中身を定義できたり、遷移するための各画面を管理できたりします。
画面の中身はPageクラスで定義し、ShellContentとしてXaml上で登録もしくは、コード上でRoutingオブジェクトに登録します。
ShellContentとして登録した場合はサイドメニューとして表示することもできます。
どちらの登録方法でも、名前付きで登録され、WebアプリのようにURI形式で呼び出すことが可能です。
初期状態としてはShellContentに③のMainPageが登録されています。
今回はこのShellクラスを使って画面遷移を実現しますが、サイドメニューがいらないよという場合には、NavigationPageを使った画面遷移の実装方法もあります。

③MainPage.xaml

メインページの画面クラスのファイルです。
他の.xamlファイルも同じですが、画面のファイル(.xaml)と実装コード(.xaml.cs)のセットになっています。
Androidアプリ開発者の方は画面=Activityと認識されるケースもあるかもしれませんが、Activityは一つです。
1つのActivity上でページの切り替えが行われます。たぶんFragmentが使われているのではないかと(適当)

④MauiProgram.cs

起動後一番最初に呼ばれる共通コードです。
Mauiアプリケーションのセットアップを行います。
初期状態としてはエントリーポイントとして①のAppクラスが指定されています。

⑤Platforms

各プラットフォーム毎のファイルを配置します。
正式な製品やOSの機能を利用する場合は、Android.Manifestやinfo.plistを編集してください。(今回は何も変更しません。)
アプリ起動時はまず初めに、各プラットフォーム毎の起動プログラムが走り(iOSであればAppDelegate等)、そこから④のMauiProgramのCreateMauiAppがコールされます。

まとめイメージ

文字だけだと伝わりずらいので、起動の流れと画面の構成を絵にしてみました。

では、特に何もせず起動してみましょう。
ツールバーで起動するプラットフォームを選択できます。

ひとまずWindowsとAndroidで実行してみます。
※実機で実行する場合は端末をデバッグモード(開発者モード)にする必要があります。

Windows
Android

同じアプリが二つのプラットフォームで実行できました。
とりあずアプリ制作の最初としては以上で完了です。
※iOS側でのデバッグや実際にリリースする際は署名関係をちゃんとしなければいけないのですが、ここでは割愛します。

UIについて

UIの画面構成についてはすべてXaml側になります。 軽くXaml内の要素について説明します。(説明用に一部除外しています。)

①ContentPage

ページの大枠です。
子には1つのViewのみ配置できます。
画面表示時(OnAppearing)等のイベントをハンドリングできます。

②VerticalStackLayout

子要素を縦に並べて配置するコンテナです。
子要素に指定がなければ幅はいっぱいに広がります。
余白等を設定できます。

③Image

画像を表示するコントロールです。
Sourceにファイルをセットしてあげることで、画像を表示できます。
Resources/Images/dotnet_bot.pngが設定されています
Aspect="AspectFit"でアスペクト比を保持しながら、コントロールのサイズに拡縮させます。

④Label

文字を表示するコントロールです。
Textに文字を設定することで表示されます
Resource/Styles/Styles.xamlに定義されているHeadlineのスタイルが設定されています。

⑤Button

ボタンを表示するコントロールです。
Label同様Textに設定することで文字を表示できます
Clickedに設定されているOnCounterClickedはコードファイル側に実装されているメソッド名になります。
クリックした回数を表示する実装となっています。

private void OnCounterClicked(object sender, EventArgs e)
{
    count++;

    if (count == 1)
        CounterBtn.Text = $"Clicked {count} time";
    else
        CounterBtn.Text = $"Clicked {count} times";
}

機能(ボタン)の追加

これからボタンを押したら画面遷移するプログラムを実装していきます。
まず、UIを編集して画面遷移ボタンを追加します

<Button
    x:Name="MovePageBtn"
    Text="画面遷移" 
    Clicked="OnMovePageClicked"
    HorizontalOptions="Fill" />

クリックされた時の処理OnMovePageClickedをMainPage.xaml.csに実装します。
自力でコードを書いてもいいですが、XamlのOnMovePageClickedにカーソルを合わせてF12(定義に移動)を押すと自動で作成してくれます。
自力で作成する場合は引数がイベントの種類によって変わってきますので注意してください。
中の処理ですが、この後画面遷移を実装しますので、今のところは謝っておきます。
DisplayAlertはメッセージダイアログの表示です。

private void OnMovePageClicked(object sender, EventArgs e)
{
    DisplayAlert("謝罪", "画面遷移はまだ未実装です!", "OK");
}

Windows
Android

新しい画面の追加

新しい画面を追加します。
プロジェクトファイルを右クリック > 追加 > 新しい項目をクリック

.NET MAUI ContentPageを選択して名前を付けて追加します。(今回はSubPageという名前にしています。)

わかりやすくするために、画面に表示されるテキストを変えましょう。
FontSize="Large"も付けて、文字を大きくします。

<Label
   Text="ページ遷移できました!"
   FontSize="Large"
   VerticalOptions="Center"
   HorizontalOptions="Center" />
作成した画面をAppShellクラスでルートに登録します。
    public partial class AppShell : Shell
    {
        public AppShell()
        {
            InitializeComponent();
            Routing.RegisterRoute(nameof(SubPage), typeof(SubPage));
        }
    }
これでSubPageという名前で画面が登録されました。

画面遷移

先ほど追加した画面をMainPageから呼び出します。
ダイアログを表示していた部分を書き換えます。
Shellに登録済みなので、URI指定で遷移先を指定することができます。
※GoToAsyncメソッドは非同期処理なので、 メソッドにasyncを付けています。

private async void OnMovePageClicked(object sender, EventArgs e)
{
    await Shell.Current.GoToAsync("SubPage");
}
これで画面遷移ボタンをクリックすると、画面遷移できます。
まだまだアプリケーションとしては乏しい状態ですが、今回はここまでにさせてください。
Windows
Android

おわりに

いかがでしたでしょうか。
今回のプログラムはAndroid、iOS、Windowsで動作します。(Mac等でも動作すると思いますが、今回除外しています。)
C#開発者の方(特にWPF経験者)であれば、簡単にモバイルアプリを作れそう!って思ってもらえたのではないでしょうか。
次回はカメラ等の共通APIへのアクセスや、プラットフォームごとの処理について触れたいと思います。(いつになるかわかりませんが。。)
利用者数という点でまだまだFlutterやReactNativeに後れを取っていますが、C#erの私としては今後MAUIが盛り上がっていくことを願っています。

KENTEMでは、様々な拠点でエンジニアを大募集しています! 建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。 recruit.kentem.jp career.kentem.jp