🔰

Avalonia UI 超入門

2024/08/31に公開

🔰 Avalonia UI ってなに?

https://www.youtube.com/watch?v=9PZVjcp3Xxc

https://avaloniaui.net/

  • 読み方:アヴァロニア ユーアイ
  • UIフレームワーク
  • .NET環境向け (C#/F#/etc...)
    • .NET Standard2.0対応
    • 最新の.NETでも古い.NET Frameworkでも動かせる
  • オープンソース、無料
  • クロスプラットフォーム

default-image

ℹ️ Avalonia UI の特徴

  • 10年以上の歴史がある
    • 最新はv11.1(2024年9月現在)
    • 程よく枯れてていい感じ
  • WPF(Windows Presentation Foundation)によく似てる
    • 体感7割が同じ
    • でも似てるだけで互換性はないよ
    • WPFを知ってるととっつきやすい(ノウハウが使える)
  • UIはOSのものを使わず独自描画
    • どこでもだいたい同じ見た目にできる
    • 描画エンジンはGoogleのSkiaやDirect2D, Vulkan
  • 対応プラットホームが多い
    • 対応済: Windows / macOS / Linux / iOS / Android / WASM / Tizen / Apple TV
    • 対応予定: visionOS
    • 独自描画なので新プラットホームに対応しやすいそう
  • デスクトップアプリが得意
    • モバイルもWASMもできるけど
    • ノウハウが多いのはデスクトップアプリ
    • デフォルトでOSのライト・ダークテーマに対応
  • MVVM[1]やMVU[2]で作れる
    • 画面はコードベースの他、XAML[3]でも作れます
      • C#+XAML+MVVMで作るパターン
      • C#+XAML+コードビハインドで作るパターン
      • F#+MVUで作るパターン
      • C#/F#だけで作るパターン

AvaloniaUI が使われてるアプリ・サービスの例

https://avaloniaui.net/showcase

🤒 Avalonia UI よくある誤解

  • WPFをクロスプラットフォーム対応したもの
    • よく似てるだけで別物
    • → 有料の「Avalonia XPF」でWPFをクロスプラットフォーム化できる
      • 「Avalonia "UI"」と「Avalonia "XPF"」は別物なので注意
  • Microsoft製
    • ✅ 主要な開発は「AvaloniaUI OÜ」という会社
    • → .NET Foundation 離脱済み
  • 画面の設計はXAML[3:1]が必須

🔄 Avalonia UIのいいところ・悪いところ

👍 いいところ

  • Microsoft公式じゃない
    • .NETの標準UI FWは迷走…
  • デスクトップアプリ開発に向いてる
    • UWP[4]やMAUI[5]と違って
  • WEBベースじゃない
    • WEBベースで出来てるFWの問題がない(パフォーマンス、サイズ、Native連携)
  • いい感じに枯れてる
    • 枯れてる=ノウハウが多い、安定している
    • 新しすぎるとChatAIも教えてくれない
  • WPFのノウハウが応用できる
    • WPFは日本語の情報も多い
  • 簡単にクロスプラットフォームアプリが作れる
    • デスクトップアプリなら比較的カンタン
    • モバイル・WEB対応もテンプレから始めれば楽にできる
    • ただし、ストア配布のメンドーな手間はある
  • WPFに比べてサイズが小さくできる
    • publish trimmedやNativeAOT[6]に対応。WPFは非対応
    • WPFが200MB~, AvaloniaUIは50MB~になるらしい
  • 対応プラットホームが多い
  • ヘッドレステストに公式で対応してる
  • WPFやMAUIやBlazerを部分的に組み合わせることができる

👎 わるいところ

  • Microsoft公式じゃない
    • .NET界隈は公式以外があんまりメジャーじゃない
    • ただし、Avalonia UI は元.NET Foundation
  • WEBベースじゃない
    • WEBのノウハウは使えない
    • ただし、Avalonia UIのStyleはCSSに似ている所がある
  • 日本語のノウハウが少ない
    • 日本語マニュアル無し
    • 基本、英語(英語なら動画チュートリアルとかもある)
    • ただし、WPF経由で日本語のノウハウが使える
  • WPFを知ってる前提のところがある
    • WPFと同じ機能はマニュアルの説明がなかったりする
    • 現状、WPF知らない人はWPF入門から始めたほうがとっつきやすいかも?
  • プラットフォームOS固有のUIが使えない
    • ファイルダイアログとかはOSのものが使える
  • MessageBoxが標準にない
    • シングルビューのプラットホーム(モバイル・WASM)を考えると仕方ないかも?
    • 再現ライブラリはいっぱいある
  • UI以外のクロスプラットフォーム処理が無い

試しに作ってみる

ソースコードは以下にあります。
https://github.com/InuInu2022/AvaloniaUIForBeginnersJa

🖥️デスクトップアプリの最小サンプルを作る

1. .NET SDKをインストール

windows
winget install Microsoft.DotNet.SDK.8
macOS
brew tap isen-ng/dotnet-sdk-versions
brew install --cask dotnet-sdk8-0-400
ubuntu
sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-8.0

https://learn.microsoft.com/ja-jp/dotnet/core/install/

2. dotnet templateでAvaloniaUIのテンプレート(Avalonia.Templates)をインストールする

最初の一回のみ
dotnet new install Avalonia.Templates

3. dotnet newでテンプレのコードを作る

「SampleApp」という名前でテンプレから作る
dotnet new avalonia.app -o SampleApp
avalonia.appでできるファイル構造
SampleApp
├obj				#無視
├App.axaml			#アプリ本体のAXAML
├App.axaml.cs			#アプリ本体のコードビハインド
├app.manifest			#基本的に触らない(Windowsで半透明ウィンドウ実現用)
├MainWindow.axaml		#メインウィンドウのAXAML
├MainWindow.axaml.cs		#メインウィンドウのコードビハインド
├Program.cs			#いわゆるエントリーポイント
└SampleApp.csproj		#プロジェクト設定ファイル
説明
  • Avalonia UIのXAMLは「AXAML」といい、*.axamlという拡張子になる
  • XAMLファイルとそれに対応するコードビハインドのcsファイルが必ずセット
  • デスクトップアプリの最小はAppMainWindow
    • モバイル・WEBだとWindowがないのでこの構造ではなくなる
  • Avalonia UIのProgram.csは省略しない事が多い(WPFはないこともある)
    • ここでBuiderパターンで色々設定することが多いため
  • app.manifestはなくても動く
    • Windowsで半透明ウィンドウ実現用の設定
  • WPFにそっくりなファイル構造・形式になる
参考WPFのテンプレで作った場合のファイルの比較
SampleWPF
├obj	#無視
├App.xaml
├App.xaml.cs
├AssemblyInfo.cs
├MainWindow.xaml
├MainWindow.xaml.cs
└SampleWPF.csproj

4. 実行

dotnet run

5. パブリッシュ

dotnet publish
  • /bin/Release/【.NETのバージョン】/【プラットフォーム】/publish/ 以下に実行ファイルが作られる
    • MSBuildスクリプトでzip圧縮や書き出し先変更などができる
  • Windows,Linuxはほぼこのままで配布可能。macOSはまだ設定が必要
単一ファイル化&サイズ削減&圧縮
SampleApp.csprojに以下を追加すると単一ファイル化&サイズ削減&圧縮できる
  <!-- 単一ファイル化 & ファイルサイズ削減 & 圧縮 -->
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <PublishSingleFile>true</PublishSingleFile>
    <TrimMode>full</TrimMode>
    <SelfContained>true</SelfContained>
    <EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
    <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
    <DebugSymbols>false</DebugSymbols>
  </PropertyGroup>

6. ソースコード

https://github.com/InuInu2022/AvaloniaUIForBeginnersJa/tree/main/ForAbsoluteBeginners/SampleApp

🌐クロスプラットフォームアプリの最小サンプルを作る

1. dotnet newでクロスプラットフォームのテンプレのコードを作る

テンプレからクロスプラットフォームのアプリを作る
dotnet new avalonia.xplat -o SampleXPlatApp
出力されるディレクトリ構造
SampleXPlatApp
├─SampleXPlatApp
│  ├─Assets
│  ├─ViewModels
│  └─Views
├─SampleXPlatApp.Android
│  ├─Properties
│  └─Resources
├─SampleXPlatApp.Browser
│  ├─Properties
│  └─wwwroot
├─SampleXPlatApp.Desktop
└─SampleXPlatApp.iOS
    └─Resources
  • avalonia.appとは違い複数プロジェクトが作られる
  • 共通処理のプロジェクト(SampleXPlatApp)と各プラットホーム処理のプロジェクトに分かれる
  • MVVMパターンで作られる
    • CommunityToolkit.Mvvmがテンプレに入ってる
    • 別に使わなくてもOK,なんならViewModel使わないでコードビハインドに書いてもいい

2. 共通処理を共通のプロジェクトで書く

  • SampleXPlatAppが共通処理
  • MainViewMainWindowという2つのビューが作られる
  • MainWindow
    • デスクトッププラットホームで最初に呼ばれるビュー
    • アプリ本体の見た目はMainViewを取り込む形
    • macOSだけにあるネイティブメニュー対応、みたいなのはXAML内で分岐処理ができる
  • MainView
    • アプリ本体のビューを書くところ
    • シングルビュープラットホーム(モバイル・WASM)はこれが直接呼ばれる形
    • 基本的にはここに書いてく
  • MainViewMainWindowの読み分けはApp.axaml.csOnFrameworkInitializationCompleted()
    • 対応するViewModelは共通でMainViewModelクラス
参考:シングルビューとウィンドウの振り分けの箇所
App.axaml.cs
public override void OnFrameworkInitializationCompleted()
{
	if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
	{
		// Line below is needed to remove Avalonia data validation.
		// Without this line you will get duplicate validations from both Avalonia and CT
		BindingPlugins.DataValidators.RemoveAt(0);
		desktop.MainWindow = new MainWindow
		{
			DataContext = new MainViewModel()
		};
	}
	else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
	{
		singleViewPlatform.MainView = new MainView
		{
			DataContext = new MainViewModel()
		};
	}

	base.OnFrameworkInitializationCompleted();
}

3. 出力するプラットホームごとのプロジェクトで実行

  • テンプレの内訳
    • SampleXPlatApp.Android
      • Android用
    • SampleXPlatApp.Browser
      • WASM用
      • 実行にはローカルサーバーが立ち上がります
    • SampleXPlatApp.Desktop
      • デスクトップアプリ用共通プロジェクト
        • 共通なのでOS固有処理は分岐処理が必要になります
      • Win/Mac/Linux用
        • 配布するには追加の設定が更にいる
    • SampleXPlatApp.iOS
      • iOS用
  • それぞれのプロジェクトでdotnet runすると実行できる
    • 一部、追加workloadのインストールやシミュレーターの実行が必要
    • メッセージに従ってdotnetコマンドで追加できます
  • テンプレに無いプラットホームも同じ様にプロジェクトを分けて作る

4. 出力するプラットホームごとのプロジェクトでパブリッシュ

  • Avalonia UI関係なく、プラットホームごとに全然手順が違うので大変
    • dotnet publishだけで済むプラットホーム、済まないプラットホーム色々ある
  • PupNet Deployを使うとApple系プラットホーム以外は簡単にパブリッシュできる

5. ソースコード

https://github.com/InuInu2022/AvaloniaUIForBeginnersJa/tree/main/ForAbsoluteBeginners/SampleXPlatApp

超入門のあとは…

ちゃんとした入門をしてみましょう

環境を充実させる

ライブラリを探す

https://zenn.dev/inuinu/articles/528550aab764e8

情報を調べる

TIPS:WPF経由で調べる

  • やりたいこと WPF」で調べて出てきた方法を「出てきた方法名 Avalonia」でもう一度調べる方法が有効です

    1. 「やりたいこと WPF」
    2. 「出てきた方法名 Avalonia」
  • そのまま使えることも

    • WPFのノウハウはとても参考になります
  • WPFからの移行方法

https://docs.avaloniaui.net/docs/get-started/wpf/

超入門じゃなくてAvaloniaUI入門が日本語でほしい!


脚注
  1. Model-View-ViewModel ↩︎

  2. Model-View-Update ↩︎

  3. .NET系で画面設定に使われるXML ↩︎ ↩︎

  4. Windows 11のフォトアプリがUWPからWin32アプリになったことで今更わかるUWPの問題点 ↩︎

  5. MAUIはXamarinベースで、モバイルファーストに作られています。そのため、普通のデスクトップアプリを作るには色々と足りていないところがあって評判が悪いです。 ↩︎

  6. CPUのネイティブコードを事前に(Ahead-Of-Time,AOT)コンパイルできる仕組みです。→Native AOT deployment ↩︎ ↩︎

Discussion