macで.netのMAUIをHello Worldしてみる

ここを参考にインストールを進める
Visual Studio for Macはもうなんか終わるっぽいのでVisual Studio Codeの手順を進める

まずは.net8をインストール
ちゃんとARM Mac版もある

MAUI ワークロードをインストールする必要があるらしい
dotnet workload install maui

駄目だった

案内の通りに
dotnet workload update
してみるも、
十分なアクセス許可がありません。昇格された特権を使用してコマンドを実行します。
でエラー。
sudoしろということかな

やはりsudoすると上手くいった
sudo dotnet workload install maui
ワークロード maui が正常にインストールされました。

.netのバージョンにあわせたxcodeが必要らしい
8.0.3の場合はXcode 15.0

Mac AppStoreではバージョン指定でインストールできなかったからとりあえず15.4を入れてみる

規約に同意してないと災いが起きそうなので一度はxcodeを起動しておく

ほらこういうのあった
AppStoreから入れただけじゃインストール終わってない

xcode-select --install
をしておく
xcode-select: note: Command line tools are already installed. Use "Software Update" in System Settings or the softwareupdate command line interface to install updates
が、既に入ってた

.net MAUI拡張をVS Codeに入れるのを忘れてた

ここから先はこのページを参考に作業する

エクスプローラーで [.NET プロジェクトの作成] または >CTRL/CMD+SHIFT+P[.NET: 新しいプロジェクト...] をクリックします。
とあるが、「.NET プロジェクトの作成」が見つからなかったので
CMD+SHIFT+P → .NET: 新しいプロジェクト → .NET MAUI アプリ
を選択

色々ファイルができた

右下の{}
をクリックしてデバイスターゲットがMacになってることを確認

VS Codeの実行とデバッグを押してみる

うごいた!

MainPage.xamlをいじって「Hello World」を「こんにちは 世界 🌏」にした
このファイルは全プラットフォーム共通っぽい

ボタンはこのようなタグで定義されている
<Button
x:Name="CounterBtn"
Text="Click me"
SemanticProperties.Hint="Counts the number of times you click"
Clicked="OnCounterClicked"
HorizontalOptions="Fill"/>
Clicked="OnCounterClicked"
とあるのでボタンをクリックするとMainPage.xaml.cs
の以下のメソッドが呼ばれる
private void OnCounterClicked(object sender, EventArgs e)
{
count++;
if (count == 1)
CounterBtn.Text = $"Clicked {count} time";
else
CounterBtn.Text = $"Clicked {count} times";
SemanticScreenReader.Announce(CounterBtn.Text);
}

だいぶ久しぶりにC#のコード読んだが「あーこんな感じだったなぁ」と思い出してきた
しかし
SemanticScreenReader.Announce(CounterBtn.Text);
ははじめて見た
スクリーンリーダーに読み上げさせるためのメソッドらしい
なるほど

なんとなくの理解

MauiProgram.csがAppをビルドしている
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

AppはMainPageというプロパティを持っていて、そこにAppShellを代入している
MainPage = new AppShell();

AppShellはアプリケーションのUIの容れ物的な役割を果たしている(?)
そしてサンプルプログラムではMainPageというコンテンツを1つ持っている
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />

そしてMainPageはUIの大部分を担っている
ただし画面上部の「Home」というバーはAppShellのほうで表示している
MainPageはそこから下の部分

テキストボックスとラベルを追加してみる
<Entry
x:Name="NameEntry"
Placeholder="Enter your name"
TextChanged="OnEntryTextChanged"
SemanticProperties.Hint="Enter your name"/>
<Label
x:Name="GreetingLabel"/>
テキスト変更時のイベント
private void OnEntryTextChanged(object sender, TextChangedEventArgs e)
{
GreetingLabel.Text = $"こんにちは、{e.NewTextValue}さん"; ;
}
反映された

VS Codeでの開発は微妙かもしれない
AppクラスでMainPageに代入している箇所
IDEではMauiApp1.MainPage
と表示され、CMDクリックするとMainPageクラスに飛ぶけれど、このプロパティの実態はMainPageクラスではない
たまたま同じ名前なだけのMainPageプロパティらしい
C#でがっつり開発したければWindowsのVisual Studio本家を使いなさいってことかなぁ

VSCodeは悪くなかった
設定でOmnisharp使うようにチェックを入れたら良い感じの挙動になった

しかし公式プラグインの説明を見るとOmniSharpは旧機能っぽい扱いなんだよなぁ
優れた Language Server 機能を活用したくない場合は、拡張機能設定に移動してdotnet.server.useOmnisharptrue に設定することで、OmniSharp の使用に戻すことができます。次に、C# Dev Kit をアンインストールまたは無効にします。最後に、VS Code を再起動してこれを有効にします。