Open29

VSCodeでAvalonia UI ~Epoxyを添えて~

いぬいぬいぬいぬ

XAMLプレビュー方法① AvantGarde

https://github.com/kuiperzone/AvantGarde

  • AvaloniaUIのプレビューアプリ

  • クロスプラットホーム

    • macOS版は用意されてないけど、dotnet runで動くらしい
  • VSCode+Avant GardeでXAMLのプレビューしながら開発できる!

  • アプリのプロジェクトとUI部分プロジェクトが別でもプレビューできる

  • ハマりポイント

    • csprojの<TargetFrameworks>に非対応。<TargetFramework>にする必要あり。
    • アプリ自体のTargetFrameworkとXAMLのTargetFrameworkを合わせないと色々不具合が...
      • EpoxyのテンプレだとUIプロジェクトがnetstandard2.0になる
    • プレビュー中 にビルドするとファイルがロックされているので失敗する
      • close solutionで一旦閉じる
      • 最新版では改良されている
    • 大きめの変更したときはdotnet restore & dotnet buildが別途必要
      • solution読み直しで動くように
    • アプリとUI部分が別プロジェクトの場合(xplatテンプレとか)に両方ビルドが必要なことがある
      • ファイルの追加、など
      • UI側の更新であっても必要(アプリ側に反映されないため
いぬいぬいぬいぬ

XAMLプレビュー方法② Live.Avalonia

https://github.com/AvaloniaUI/Live.Avalonia

  • Avaloniaでhot reloadingを実現するライブラリ
  • VSCode + Live.AvaloniaでXAMLのプレビューしながら開発できる!
  • 表示だけじゃなくてアプリ自体も普通につかえる
  • ハマリポイント
    • コードに手を入れる箇所がそこそこ多い
    • axamlファイルをdotnet watch対象にcsprojで指定する必要あり
    • WindowのXAML設定がスキップされちゃうのでコードで指定する必要あり
    • dotnet runのときにターゲットフレームワークを指定する必要あり
      • アプリが複数フレームワーク向けプロジェクトで作られてる時?
  • MVUとかで作る時に向いてる

https://gist.github.com/InuInu2022/84326613378b817e4e2af29bf762d77d

いぬいぬいぬいぬ

VSCodeでAvalonia UIをやるとき入れたほうがいい拡張・設定

拡張

C#/dotnet基本

Avalonia

設定

  • AXAML(Avalonia UI用XAML)のXSDの設定
    • Xml Complete拡張でデフォで設定済

dotnet cli

snippets

Epoxy

Epoxy property changed event
csharp.jsonに追加
	"Epoxy property changed": {
		"prefix": "propch",
		"body": [
			"[PropertyChanged(nameof(${1:propname}))]",
			"[SuppressMessage(\"\",\"IDE0051\")]",
			"private ValueTask ${1:propname}ChangedAsync(${2:type} value)",
			"{",
			"$3",
			"\treturn default;",
			"}"
		],
		"description": "Epoxy property changed event"
	},
いぬいぬいぬいぬ

Avalonia UIのパーツの探し方・調べ方

VSCodeじゃなくても便利。

ギャラリー・サンプルアプリを使う

WASM Playground

  • 公式のWASMサンプル
  • Windows Storeにあるものよりサンプルが多い
  • その場でいじれて便利(VSCode環境だと特にね!)
  • wasmなので動かないものもある

FluentAvalonia Samples

  • FluentAvaloniaのギャラリーアプリ
    • FluentAvaloniaを使う時用だけど、標準パーツも一部見れる
  • 自分でビルドする必要がある(でもかんたん)
  • 直接いじれないけど実際に動作する
  • 標準パーツ、追加パーツ(WinUIの移植)の両方が見れる
    • Fluentな見た目で確認できる
  • Show Definitionでプロパティとかの定義も見れる
  • たまにサンプルソースがリンク切れ
  • FluentAvalonia経由でWinUIを使う時用
  • FluentAvalonia Samplesより細かく設定変えられたりする
いぬいぬいぬいぬ

Avalonia 日本語対応 状況と対策

ざっくりまとめ

  • v0.10.x系は使わない(日本語対応不十分)
  • v11.x系なら基本的にOK
    • ただし、wasmはシステムデフォルトのフォントを参照できないwasm自体の制限がある
      • 日本語対応フォントの指定や埋め込みが必要

v0.10.xの場合

以下は古い情報です。v11系以降を使おう
  • TextBoxなどで日本語は豆腐になる(仕様)
  • 日本語のフォントを指定すればOK
  • css風に各OSの標準日本語フォントを書けばどのプラットホームでも表示できる
FontFamily="Meiryo UI, Hiragino Sans, Noto Sans CJK JP"
  • メインWindowのxaml中でTextBoxとかにまとめてスタイルすれば全部指定される

    • Appの方がいいかも?Avant Gardeでページ単体を見る時に反映されない
  • IMEはインライン入力できない

    • Windows10+FluentAvalonia+v0.10.18だと入力できることもある
    • 逆に一切入力できなくなることもある…めっちゃ不安定
    • コピペはイケル
  • 後ろから3文字目?が消えるバグ に遭遇

    • 文字列の置き換えやフォント指定で治ったりする
    • 再発することもある

v11.xの場合

以下は古い情報です。v11正式版以降を使おう

wasm

private static void Main(string[] args) => BuildAvaloniaApp()
        .UseReactiveUI()
        .With(new FontManagerOptions
        {
            FontFallbacks = new[]
            {
                new FontFallback
                {
                    FontFamily = new FontFamily("avares://WebTest/Assets/Fontquan-XinYiGuanHeiTi.ttf#Fontquan")
                }
            }
        })
        .SetupBrowserApp("out");

#以降にフォント名を記載しないとうまく動かない(スペースも大事)。

FontFamily = new FontFamily("avares://path/to/font/NotoSansCJKjp-Regular.otf#Noto Sans CJK JP)

Font

WithInterFont()

AppBuilderのところでWithInterFont()を呼ぶと、OSSのInterフォントが呼ばれる。
不要な場合は外す。

https://rsms.me/inter/

https://github.com/AvaloniaUI/Avalonia/discussions/11413

アプリ全体でフォント指定

https://github.com/AvaloniaUI/Avalonia/discussions/14466

<Style Selector=":is(TopLevel)">
    <Setter Property="FontFamily" Value="Comic Sans MS"/>
</Style>

https://github.com/AvaloniaUI/Avalonia/discussions/7539

<x:Double x:Key="ControlContentThemeFontSize">14</x:Double>

FontPicker

https://www.nuget.org/packages/FontPickerAvalonia

v0.10.x向けライブラリなので少し手直しする必要がありそう。

いぬいぬいぬいぬ

Avalonia対応ライブラリ・サンプル

App template

  • Avalonia MDI Skeleton
    • MDIのデスクトップアプリのテンプレに使えるサンプルアプリ
    • 「MapGuide Maestro」というアプリを基にしている
    • WASM対応、オンラインdemo
    • タブ、リッチテキスト、
    • CommunityToolkit.Mvvm、StrongInject、PupNet Deploy
  • SideScroll
    • クリックすると詳細を横にスクロールして表示していくタイプのアプリを作れるライブラリ
    • タブ、チャート、リッチテキスト、ログ、ブックマーク、スクリーンキャプチャ、シリアライズ機能などがある
  • Avalonia AOT

Control

Theme & Control

MVVM

  • Epoxy
  • Mvvm.Navigation
    • NavigationのコードをSource Generatorで自動生成するライブラリ
  • Stylet.Avalonia
    • WPF/UWPのCaliburn.MicroにインスパイアされたMVVMライブラリ

MVU

Rx

SourceGenerator

l8n/i18n

DI / GenericHost

Other

いぬいぬいぬいぬ

Avalonia XPFとは

https://avaloniaui.net/XPF

  • Avalonia社が提供する 企業向け商用サービス
  • 既存のWPFアプリをクロスプラットフォーム移植してくれるというもの
    • 技術的にはモバイルやWASM対応もできるけど、まずはDesktopむけ
  • すでにアプリがある会社が利用するもので個人開発者は基本的に関係ない
  • 内部的にAvaloinia UIの仕組みが使われているらしい
  • インディーライセンス準備中(2024-05)
Avalonia UI Avalonia XPF
これはなに UIフレームワーク サービス
価格 無料 有料
誰向け 誰でも 企業のみ
いぬいぬいぬいぬ

日本語がわかる人がつくってるっぽいAvalonia関係

日本語情報がほとんどないAvaloniaだけど、この辺の作者さんに聞けば色々わかることがあるかも?

アプリ

ライブラリ

いぬいぬいぬいぬ

Avalonia v11情報

v11.1 Release

https://github.com/AvaloniaUI/Avalonia/releases/tag/11.1.0

https://avaloniaui.net/blog/avalonia-11-1-a-quantum-leap-in-cross-platform-ui-development

v11.1 beta

https://github.com/AvaloniaUI/Avalonia/discussions/14922
https://github.com/AvaloniaUI/Avalonia/discussions/15507

  • HyperLinkButton control が追加
  • XAML中でWPFにもあるUpdateSourceTriggerが使えるように
  • tvOS/AndroidTV/TizenTVのサポート。リモコン操作できるように
  • LauncherAPIが実装
    • フォルダ/ディレクトリを開く、関連付けアプリの起動が同じ記述でできるように
  • 内部のSkiaがSkiaSharp 3.0に

v11.0 Released!

  • 2023-07-05リリース

Avalonia for Visual Studio Code (Early Access)

  • ついに公式のVSCode向け拡張が発表
    • XAML補完
    • プレビューワ
  • 支援者むけに先行公開中
    • 普通につかえるようになった
    • https://github.com/AvaloniaUI/AvaloniaVSCode
    • ただし、v11.0.2以前じゃないとうまく動かないらしい
    • 他にも初回の反映に時間がかかるなど色々と細かい使い勝手が良くない問題あり

対応ライブラリ

  • Epoxy
    • Epoxy.Avalonia11 というのがリリースされた(v0.10系以前とは別に分かれた)
  • FluentAvalonia
    • v2.0.0がリリース
    • 以前なかった新しいControlも追加されている模様
  • NP.Ava.UniDock
    • NP.Avalonia.UniDockのv11対応版
    • 2023年末にやっと出た
いぬいぬいぬいぬ

migration to v11 memo

Porting guide

https://github.com/AvaloniaUI/Avalonia/wiki/Avalonia-11-Porting-Guide

porting guideに無い箇所

  • file選択/saveダイアログ系は新apiに変更されている
  • With(new Win32PlatformOptions… は不要の様子
  • drag and drop処理は以前のままだと System.ObjectDisposedException 出ることがある
    • Dispatcher.UIThread.InvokeAsync 経由でVMの処理を呼んでいた箇所
    • そのままVMのメソッドを呼べば動くように
await vm.DropFileEventAsync(e)
	.ConfigureAwait(false);
  • Bindingのランタイムエラーがよく出るように
    • どうもこういうものらしい(仕組み上しかたないとのこと)

ライブラリ

  • Epoxy
    • CommandFactory -> Command.Factory
  • FluentAvalonia
    • SymbolIconのsymbol指定文字列が一部無くなっている(*Fill系)
      • symbol指定文字列はv2.0.0のサンプルアプリで検索できる
    • ui:SplitButtonに対するスタイル指定がエラーに
      • そもそも使っていなかったので消したらエラー無くなった
いぬいぬいぬいぬ

XAMLプレビュー方法③:Avalonia for Visual Studio Code

https://github.com/AvaloniaUI/AvaloniaVSCode

公式のVSCode拡張。

  • プレビュー可能な公式VSCode拡張

    • XAML補完とかもある
  • 現時点の問題点

    • v11.0.2以下でないとプレビューがうまくいかない
    • 初回表示までにとても時間がかかる
    • クリック操作などは機能しない (一部直ってた)

プレビュー機能だけで言うと①や②の方が現時点では実用的。

いぬいぬいぬいぬ

XAMLプレビュー方法④ HotAvalonia

HotReloadを実現するライブラリ。

https://github.com/Kir-Antipov/HotAvalonia

ドキュメントを読む限り、 Live.Avaloniaより使いやすそうい。

  • dotnet watch 不要 (普通にビルドしても有効になる)
    • ただし.NET 7以降はデバッガー接続起動かwatch推奨らしい
  • 手を入れる行数少ない
  • XAMLのhotreloadなのでNXUIとかXAML使わないライブラリと組み合わせられないのに注意
いぬいぬいぬいぬ

Dock.Avalonia 関連

不穏な雰囲気

  • 一瞬ライセンスがAGPLに変わってすぐにMITに戻った
    • OSSでつかってほしいのかな?
  • github issuesが消えた
    • サポートしない方針?

描画系

  • プレビュー系と相性が悪い
    • HotAvalonia, AvantGardeともに更新がエラーになる
    • 生産性は良くない
  • 公式DevToolでツリーが追えない
    • Dockの中に隠されてしまう

FluentAvalonia + Dock.Avalonia

  • そのままだと見えなくなる
  • RGBのColorを指定すればとりあえず見えるようにはなる
  • RGBAのBrushを指定できない
    • なのでテーマ(Dark/Light)の切替は手動
      • Converterで持ってきたい所…
App.axaml
    <Application.Resources>
      <idcr:ControlRecycling x:Key="ControlRecyclingKey" TryToUseIdAsKey="True" />
      <Color x:Key="RegionColor">Transparent</Color>

      <SolidColorBrush x:Key="DockApplicationAccentBrushLow">#007ACC</SolidColorBrush>
      <SolidColorBrush x:Key="DockApplicationAccentBrushMed">#1C97EA</SolidColorBrush>
      <SolidColorBrush x:Key="DockApplicationAccentBrushHigh">#52B0EF</SolidColorBrush>
      <SolidColorBrush x:Key="DockApplicationAccentForegroundBrush">#F0F0F0</SolidColorBrush>
      <SolidColorBrush x:Key="DockApplicationAccentBrushIndicator">#007ACC</SolidColorBrush>

      <SolidColorBrush x:Key="DockThemeBorderLowBrush" Color="#808080" />
      <SolidColorBrush x:Key="DockThemeBackgroundBrush" Color="#F0F0F0" />
      <SolidColorBrush x:Key="DockThemeAccentBrush" Color="#FF8888" />
      <SolidColorBrush x:Key="DockThemeForegroundBrush" Color="#FEFEFE" />
      <SolidColorBrush x:Key="DockThemeControlBackgroundBrush" Color="#0000F0" />
    </Application.Resources>
いぬいぬいぬいぬ

UniDock関連

  • NP.Ava.UniDock の方でv11対応版出た
    • NP.Avalonia.UniDockはv0.10以前

サンプルコード

  • なぜかgit submoduleで必要ライブラリが全部落としてこれない…
  • Releaseビルドだと動いた
    • Debugビルドでもnugetに上がってるライブラリだけで動くようにcsproj書き換えちゃってもいいかも

Style

注意点

  • 通常のName属性指定してもStyle指定に使えない
    • 代わりに、ItemPresenterClassesでクラス指定できる

デフォルトの指定を消して、全体のテーマを反映させる

背景色

デフォルトでは強制White指定なのでダークテーマとかで何も見えないことがある。

<Style Selector="np|DockItemPresenter">
      <Setter Property="Background"
          Value="Transparent"/>
    </Style>
    <Style Selector="np|TabbedDockGroup">
      <Setter Property="Background"
          Value="Transparent"/>
    </Style>
    <Style Selector="np|StackDockGroup">
      <Setter Property="Background"
          Value="Transparent"/>
    </Style>

ただし、これだけでは{Tabbed}StackGroupのヘッダー部分と切り離したフローティングウィンドウには反映されない。

issueにsimplethemeを反映させる例があった。
https://github.com/npolyak/NP.Ava.UniDock/issues/16#issuecomment-1938418447

DockItemのHeaderを消す

xaml
<np:DockItem
    ItemPresenterClasses="NoHeader"
    />

対象のDockItemItemPresenterClasses属性でスタイルのクラスを設定する(例:NoHeader)。

xaml
<Style Selector="np|DockItemPresenter.NoHeader">
    <Setter Property="ShowHeader"
          Value="False"/>
</Style>

ShowHeader=Falseで消える。

いぬいぬいぬいぬ

Avalonia XAML Tips

拡張子は.axaml

.axamlにするのが推奨されている。
.xaml.xmlでも動くらしいが、エディタのAvalonia向け拡張などが動かないことがある。
(他のXAML使うフレームワークと区別つかない為)

Xamarin.AndroidのXAMLが.axmlなので混同しないように注意

namespaceにはusing:YourNamespace.YourAppが使える

WPFなどのXAMLと違ってxml namespaceにはusing:YourNamespace.YourAppという記法が使える。C#のコード中とほぼ同じなのでラク

axaml
xmlns:ui="using:FluentAvalonia.UI.Controls"

https://docs.avaloniaui.net/docs/basics/user-interface/introduction-to-xaml#using-prefix

※WPFと同じ記法clr-namespaceも使える

Bindingで親要素は$parent

  • さらにその親は $parent[n]でどんどん階層を上がって行ける
    • $parent=$parent[0]; 一つ目の親が0
  • 詳細:Binding to an Ancestor
  • 親要素のWindow: $parent[Window]

Bindingで祖先のcontrolは $parent[ControlName]

  • $parent[Window]でウィンドウ参照できる
  • もっと上は $parent[ControlName; n]でどんどん階層を上がって行ける

Bindingで別のコントロールのViewModelを参照するにはキャスト&再ビルド

  • ((vm:MyUserControlViewModel)DataContext)とする
  • ホットリロードだとエラーになる。要再ビルド
<Button Command="{Binding $parent[ItemsRepeater].((vm:MyUserControlViewModel)DataContext).DoItCommand}"
                CommandParameter="{Binding ItemId}"/>

https://docs.avaloniaui.net/docs/basics/data/data-binding/compiled-bindings#type-casting

Bindingで否定は!

<Element IsEnabled = "{Binding !#someElem.IsEnabled}" />

非同期Bind(Task<T>にbind)

  • Task<T>を返す非同期処理にBindできる
<TextBlock Text="{Binding MyAsyncText^, FallbackValue='Wait a second'}" />

親要素と同じ幅を指定するのは "{Binding $parent.Bounds.Width}"

  • $parent.Width だとダメ。Bounds経由で。
いぬいぬいぬいぬ

【解決】Epoxy + Avalonia でCommandのバインドがうまくいかない時

  • EpoxyにはEventBinderというCommandがバインドできなくてもバインドできる便利機能がある
axaml
<NoCommandControl>
  <epoxy:EventBinder.Events>
      <epoxy:Event EventName="TargetEvent" Command="{Binding MyCommand}" />
  </epoxy:EventBinder.Events>
</NoCommandControl>
  • でもAvaloniaだとEventBinderが使えないことがちょくちょくある
    • SliderとかのPointWheelEvent
    • DragDrop.DropEvent
  • ランタイムエラー: 'Epoxy.Event'.'Command': 'Null value in expression '{empty}' at ''.'(Event #nnnnnnnn)
    • なんもわからん
  • WPF版Epoxyだともう少し色々できたような…

解決策1: Ancher/Pileを使う

  • VMでWindow.LoadedにバインドしたReadyコマンドの中とかで、piledControl.SomeEventChanged += MyCommand()する
  • HotAvaloniaのhotreloadと相性悪い場合にも使える

解決策2: あきらめてコードビハインド

  • DragDrop.DropEventはPile/Anchor使っても上手くいかなかった
    • 正直よく使うから何とかしたい…
  • HotAvaloniaのhotreloadと相性悪い?

解決策:Epoxy1.15のFountain/Wellを使う

  • EventBinder代替が追加された!!
  • 作者さんがわざわざ対策していただいた!
  • ダメだったDragDrop.DropEventがサクッとかける!
  • 今後はこっちで
いぬいぬいぬいぬ

CodingSeb.Localization for Avalonia v11

  • nuget v1.3.0 MethodMissingのランタイムエラー
  • AvaloniaSample
    • v11.0.*ではビルドが通らない
    • Fork
  • CodingSeb.Localization.Locが見つからないビルドエラー
    • nugetのCodingSeb.Localizationではなく、git submoduleなどでCodingSeb.Localizationに参照するとうまくゆく
  • readme.md の xmlns が正しくない(WPFでも問題あり)
readme.md
xmlns:loc="clr-namespace:Localization;assembly=Localization"
rewrite
xmlns:loc="clr-namespace:CodingSeb.Localization;assembly=CodingSeb.Localization"
いぬいぬいぬいぬ

フォーラムとか

いぬいぬいぬいぬ

バッジ

Made with Avalonia UI

Made with Avalonia UI

[![Made with Avalonia UI](https://img.shields.io/badge/Made_with-Avalonia_UI-blue.svg?logo=&style=flat)](https://avaloniaui.net/)

Made with Epoxy

Made with Epoxy

[![Made with Epoxy](https://img.shields.io/badge/Made_with-Epoxy-blue.svg?style=flat)](https://github.com/kekyo/Epoxy)
いぬいぬいぬいぬ

Avalonia UIドッキングライブラリ比較 (docking libs)

  • Dock.Avalonia
  • UniDock
    • 老舗ライブラリその2
    • テーマ対応は自作する必要あり
    • UniDock関連
  • PixiDocks
    • PixiEditorで使われているドッキングライブラリ
    • おそらくDock.Avalonia派生
  • Avalonia.UpDock
    • 最近リリースされた開発中?のドッキングライブラリ
    • Dock/UniDockの問題を解決するために作られたらしい
      • 標準のTabControl/TabItemベースなのでテーマの反映がラク
    • そんなに多機能ではない
    • ライセンス不明
      • MITと判明
    • Avalonia.UpDock関連
  • ReDocking
    • Beutilの作者さんによるドッキングライブラリ
    • 他のライブラリとは異なり、タブではなくツールバーのアイコンでレイアウトを変更
      • アイコンの右クリックからウィンドウ化、ドッキング制御
    • 見た目はFleuntAvalonia前提
    • v11.1.x以降

比較表

Dock.Avalonia UniDock PixiDocks UpDock ReDocking
GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars GitHub Repo stars
License MIT MIT MIT MIT MIT
nuget NuGet Version NuGet Version - - NuGet Version
Framework net6.0/8.0 net8.0 net8.0 net7.0 net8.0
外部テーマ反映 x x ? x
レイアウト保存復元 x ?
いぬいぬいぬいぬ

Avalonia.UpDock 関連

https://github.com/jupahe64/Avalonia.UpDock

  • 最近リリースされた開発中?のドッキングライブラリ
  • Dock/UniDockの問題を解決するために作られたらしい
    • 標準のTabControl/TabItemベースなのでテーマの反映がラク
  • そんなに多機能ではない
  • ライセンス不明
    • MIT

入れ子タブのウィンドウ化

  • DockingTabControlの入れ子をすると子側がウィンドウ化できない
<up:DockingHost>
    <up:DockingTabControl>
        <TabItem Header="Outer Tab A">
            <up:DockingTabControl>
                <!--  This Tab cannot be dragged out to a new floating window -->
                <TabItem Header="Inner Tab A">
                    <TextBlock Margin="5">Content</TextBlock>
                </TabItem>
            </up:DockingTabControl>
        </TabItem>
    </up:DockingTabControl>
</up:DockingHost>
  • ただし、DockingHostを入れ子にすると有効
    • 親子関係の入れ替えや並列化しないならあり
<up:DockingHost>
    <up:DockingTabControl>
        <TabItem Header="Outer Tab A">
            <!-- Add DockingHost here-->
            <up:DockingHost>
                <up:DockingTabControl>
                    <!--  This Tab can be dragged out to a new floating window -->
                    <TabItem Header="Inner Tab A">
                        <TextBlock Margin="5">Content</TextBlock>
                    </TabItem>
                </up:DockingTabControl>
            </up:DockingHost>
        </TabItem>
    </up:DockingTabControl>
</up:DockingHost>
いぬいぬいぬいぬ

Avalonia Icon ライブラリ

FluentAvalonia

  • UIコンポーネントライブラリだが一部アイコン指定可能
  • アイコンライブラリ:fluentui-system-icons

FluentIcons.Avalonia

https://www.nuget.org/packages/FluentIcons.Avalonia/

  • FluentAvaloniaで指定できない種類も使える
    • FluentAvaloniaようにnugetが分かれている
  • アイコンライブラリ:fluentui-system-icons

使い方

  • MarkupExtensionはAvaloniaでは動かない?
    • 下の様にするとラク
Resourceとして定義
  <UserControl.Resources>
    <ic:SymbolIconSource Symbol="ArrowLeft" x:Key="ArrowLeft" IsFilled="True" />
  </UserControl.Resources>
StaticResourceとして呼び出し
IconSource="{StaticResource ArrowLeft}"

LucideAvalonia

https://www.nuget.org/packages/LucideAvalonia

  • アイコンライブラリ:Lucide
    • アイコン数:1509 (調査時点)
  • v11.1以降限定

Projektanker.Icons.Avalonia

https://www.nuget.org/packages/Projektanker.Icons.Avalonia

  • アイコンライブラリ:FontAwesome 6 Free & Material Design Icons

使い方

FluentAvaloniaでIconSourceとして指定する場合、ThemeVariant対応に問題あり
https://github.com/Projektanker/Icons.Avalonia/issues/104

TablerIcons.Avalonia

https://www.nuget.org/packages/TablerIcons.Avalonia

  • アイコンライブラリ:tabler icons
    • アイコン数:5450 (調査時点)
いぬいぬいぬいぬ

Avalonia UIでNative AOTに対応させる

  • Avalonia UIは NativeAOT に対応している
  • ただし、いろいろ設定が必要
  • ライブラリも、NativeAOT Readyなものを選ぶ必要がある

前提

  • SDK: .NET SDK 8.0
    • NativeAOT自体は6.0ぐらいから使えるが、最新がいい
  • C++コンパイラ
    • WindowsならVS2022+「Desktop development with C++」

csproj

 <PropertyGroup>
+    <!-- AOT有効化。trimも同時に有効になる -->
+    <PublishAot>true</PublishAot>
+    <!-- デバッグシンボルを除外 -->
+    <StripSymbols>true</StripSymbols>
+    <!-- 最適化オプション 'Size' or 'Speed' -->
+    <OptimizationPreference>Size</OptimizationPreference>
+    <!-- カルチャ依存無効化でサイズ削減 -->
+    <InvariantGlobalization>true</InvariantGlobalization>
 </PropertyGroup>
注意が必要なオプション
+    <!-- リフレクションフリーモード;リフレクションAPIの大部分が無効化 -->
+    <IlcDisableReflection>true</IlcDisableReflection>
Debug用
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PublishAot>false</PublishAot>
    <StripSymbols>false</StripSymbols>
</PropertyGroup>

trimmingオプション

NativeAOTはtrimが有効になるため、そのままだと必要以上に削除されて動かないことが良くある。

https://learn.microsoft.com/ja-jp/dotnet/core/deploying/trimming/trimming-options?pivots=dotnet-8-0#root-descriptors

*.csproj
 <PropertyGroup>
+    <TrimMode>partial</TrimMode>
 </PropertyGroup>
 <ItemGroup>
+  <TrimmerRootDescriptor Include="Avalonia.xml" />
 </ItemGroup>
Avalonia.xml
<linker>
	<!-- App -->
	<assembly fullname="MyAvaloniaAppName" preserve="All" />
	<!-- Avalonia Themes -->
	<assembly fullname="Avalonia.Themes.Fluent" preserve="All" />
</linker>

警告有効化

<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>

代替検討

  • DataGridはNativeAOT非対応 issues
  • TreeDataGridはNativeAOT対応(ただしバグが多い)

ライブラリ

テンプレ

https://github.com/lixinyang123/AvaloniaAOT/tree/main

参考ドキュメント

https://learn.microsoft.com/ja-jp/dotnet/core/deploying/native-aot/
https://github.com/dotnet/runtime/tree/main/src/coreclr/nativeaot/docs
https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/optimizing.md
https://ufcpp.net/blog/2023/3/string-order/

いぬいぬいぬいぬ

Avalonia 非公式マニュアル

A button with an added drop-down chevron to visually indicate it has a flyout with additional actions.

Avalonia.Controls/DropDownButton.cs

DataGrid

DataGridColumn.Width

DataGridColumnの子クラスはWidth(列の幅)プロパティに数値、*, Auto以外も指定できる。

  • SizeToCells
    • セルの中身の幅に列の幅を合わせる
  • SizeToHeader
    • セルのヘッダーの幅にに列の幅を合わせる

なぜかマニュアルに記載ない。
https://docs.avaloniaui.net/docs/reference/controls/datagrid/datagridcolumns

Notifications

https://reference.avaloniaui.net/api/Avalonia.Controls.Notifications/Notification/

  • ContentCatalogにはあるけどマニュアルにない通知Control
  • アプリウィンドウ内の通知
  • 使い方がちょっと特殊
xaml
<!--  通知を出したい所に書く -->
<WindowNotificationManager x:Name="ControlNotifications" />

<!--  ボタンで呼び出すときは、CommandParameterにNotification要素を指定する -->
<Button
    Content="Show XAML only Notification"
    Command="{Binding #ControlNotifications.Show}">
    <Button.CommandParameter>
        <Notification Title="Title" Message="Message" OnClick="NotificationOnClick" />
    </Button.CommandParameter>
</Button>
いぬいぬいぬいぬ

【解決】.NET9.0でEpoxyでビルドが失敗する

エラー:MSB6003

【Path】\.nuget\packages\epoxy.build\1.15.0\build\Epoxy.Build.targets(111,5): error MSB6003:
      指定されたタスク実行可能ファイル "cmd.exe" を実行できませんでした。
      System.IO.DirectoryNotFoundException:  作業ディレクトリ "【Path】\.nuget\
      packages\epoxy.build\1.15.0\tools\net9.0" が存在しません。
         at Microsoft.Build.Tasks.Exec.GetWorkingDirectory()
         at Microsoft.Build.Utilities.ToolTask.GetProcessStartInfo(String pathToTool      , String commandLineCommands, String responseFileSwitch)
         at Microsoft.Build.Utilities.ToolTask.ExecuteTool(String pathToTool, String       responseFileCommands, String commandLineCommands)
         at Microsoft.Build.Tasks.Exec.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands)
         at Microsoft.Build.Utilities.ToolTask.Execute()

Windows環境。
【Path】は自分のnugetのインストールパス。
内部で使っているツールが.NET9向けにまだない模様。

対策

  • Epoxy v1.15.0以降にアップデートする。

または、.NET8をつかう。

  • global.jsonでsdkのバージョンを.NET8に固定する。
  • dotnet new globaljson でglobal.jsonを作成できる
dotnet new globaljson --sdk-version 8.0.404