VSCodeでAvalonia UI ~Epoxyを添えて~
目次
- 基本準備
- UIプレビュー
- 対策
- 知識
XAMLプレビュー方法① 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側の更新であっても必要(アプリ側に反映されないため
- csprojの
XAMLプレビュー方法② Live.Avalonia
- Avaloniaでhot reloadingを実現するライブラリ
- VSCode + Live.AvaloniaでXAMLのプレビューしながら開発できる!
- 表示だけじゃなくてアプリ自体も普通につかえる
- ハマリポイント
- コードに手を入れる箇所がそこそこ多い
- axamlファイルをdotnet watch対象にcsprojで指定する必要あり
- WindowのXAML設定がスキップされちゃうのでコードで指定する必要あり
-
dotnet run
のときにターゲットフレームワークを指定する必要あり- アプリが複数フレームワーク向けプロジェクトで作られてる時?
- MVUとかで作る時に向いてる
VSCodeでAvalonia UIをやるとき入れたほうがいい拡張・設定
拡張
C#/dotnet基本
-
C# DevKit
- 商用利用は本家VisualStudioと同ライセンス
-
C# for Visual Studio Code (powered by OmniSharp)
-
Roslynator https://marketplace.visualstudio.com/items?itemName=josefpihrt-vscode.roslynator
- 最新では、Analyzerとしてprojectごとに導入するのが推奨されている
-
fakesharper https://marketplace.visualstudio.com/items?itemName=fakesharper.fakesharper
-
VS Sharper for C# https://marketplace.visualstudio.com/items?itemName=eservice-online.vs-sharper
-
MSBuild project tools https://marketplace.visualstudio.com/items?itemName=tintoy.msbuild-project-tools
-
Visual NuGet https://marketplace.visualstudio.com/items?itemName=FullStackSpider.visual-nuget
-
vscode-solution-explorer https://marketplace.visualstudio.com/items?itemName=fernandoescolar.vscode-solution-explorer
Avalonia
- Avalonia for VSCode - Visual Studio Marketplace
- Avalonia UI Templates
- Xml Complete https://marketplace.visualstudio.com/items?itemName=rogalmic.vscode-xml-complete
-
.NET Meteor
- MAUI向けhotreload拡張がv5.0でAvaloniaにも対応したらしい?
- ドキュメントなし
- XAMLのコード補完がAvaloniaVSを基にしている、ということらしい…
-
XAML Styler
- VS本家にあるやつのVSCode版(cli版を内部的に利用)
- Format AXAML/XAML files
- Provides schema for Settings.XamlStyler files
設定
- AXAML(Avalonia UI用XAML)のXSDの設定
- Xml Complete拡張でデフォで設定済
dotnet cli
- avalonia-dotnet-templates
-
Epoxy-avalonia-
Epoxyを使う場合配布終了
-
snippets
Epoxy
Epoxy property changed event
"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でプロパティとかの定義も見れる
- たまにサンプルソースがリンク切れ
WinUI3 Gallery
- FluentAvalonia経由でWinUIを使う時用
- FluentAvalonia Samplesより細かく設定変えられたりする
Avalonia 公式 Developer Tools
DebugビルドでF12を押すと、WEBブラウザの開発者向けツールに似た、Developer Toolsが起動する。
起動しない場合は InitializeComponent
内で以下のように呼び出す。
#if DEBUG
this.AttachDevTools();
#endif
Avalonia 日本語対応 状況と対策
ざっくりまとめ
- v0.10.x系は使わない(日本語対応不十分)
- v11.x系なら基本的にOK
- ただし、wasmはシステムデフォルトのフォントを参照できないwasm自体の制限がある
- 日本語対応フォントの指定や埋め込みが必要
- ただし、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正式版以降を使おう
-
preview以前はIMEのインライン入力に対応したが、色々と問題がある
- RC1
- Preview8
- ENTERキーを押さずに確定すると文字列が消えるバグ
-
AutoCompleteBox cannot input any by IME while selected an item. · Issue #11426 · AvaloniaUI/Avalonia
- 中国語IMEで発生するので日本語でも発生するかも
-
Pre-edit content doesn't clean up well with Japanese IME · Issue #11309 · AvaloniaUI/Avalonia
- 未確定文字列がDeleteキーで正しく消せない問題
- Preview7
-
Automatic copying of IME text when clicking on another TextBox · Issue #11292 · AvaloniaUI/Avalonia
-
TextBox
に入力した文字列が別のTextBox
クリック時にコピーされちゃうバグ
-
-
Automatic copying of IME text when clicking on another TextBox · Issue #11292 · AvaloniaUI/Avalonia
- Preview6
-
IME preedit doesn't support cursor navigation · Issue #10933 · AvaloniaUI/Avalonia
- 未確定文字列状態でカーソルキーをつかってカーソルを動かせない
-
IME preedit doesn't support cursor navigation · Issue #10933 · AvaloniaUI/Avalonia
- 発生バージョン不明
-
IMEの種類問題
- あたらしいMS-IMEだと問題ないが、古いMS-IMEやGoogle IMEだと問題が発生するバグがある
- 開発者によるとテストされていないとのこと
- 古いMS-IMEはWin11でもビルドインで、新しいMS-IMEで問題が起きるアプリが多いので、特に問題がある
- あたらしいMS-IMEだと問題ないが、古いMS-IMEやGoogle IMEだと問題が発生するバグがある
wasm
- v11.x以降でも豆腐フォント問題がある(仕様)
- システムのデフォルトのフォントを指定できない
- フォントアセットを取り込んで指定する
- wasm向けにはfontアセットの指定が必要
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フォントが呼ばれる。
不要な場合は外す。
アプリ全体でフォント指定
<Style Selector=":is(TopLevel)">
<Setter Property="FontFamily" Value="Comic Sans MS"/>
</Style>
<x:Double x:Key="ControlContentThemeFontSize">14</x:Double>
FontPicker
v0.10.x向けライブラリなので少し手直しする必要がありそう。
Avalonia対応ライブラリ・サンプル
-
AvaloniaCommunity/awesome-avalonia: A collection of interesting libraries and tools for Avalonia project.
- 基本的なものは↑ここに
- 以下awesome-avaloniaにないもの
- ✔は動作確認済、なしは未確認
- ➕はawesome-avaloniaに追加済
App template
-
Avalonia MDI Skeleton
- MDIのデスクトップアプリのテンプレに使えるサンプルアプリ
- 「MapGuide Maestro」というアプリを基にしている
- WASM対応、オンラインdemo
- タブ、リッチテキスト、
- CommunityToolkit.Mvvm、StrongInject、PupNet Deploy
-
SideScroll
- クリックすると詳細を横にスクロールして表示していくタイプのアプリを作れるライブラリ
- タブ、チャート、リッチテキスト、ログ、ブックマーク、スクリーンキャプチャ、シリアライズ機能などがある
-
Avalonia AOT
- NativeAOT対応させるためのテンプレート
- 参考:Avalonia UIでNative AOTに対応させる
Control
- ➕Avalonia Labs
- 公式の実験的UI
- AsyncImage、TabControl、FlipView、NavigationControl
-
MediaPlayerUI.NET
- Avalonia/WPFに対応したメディアプレイヤーUI
- ただし、Avalonia版は非商用利用限定のBASSを利用するので制限あり
- Laminar.Avalonia.SelectAndMove
- ➕wieslawsoltes/ColorPicker: Avalonia ColorPicker control
- wieslawsoltesさんによるカラーピッカー
- ➕wieslawsoltes/NodeEditor: A node editor control for Avalonia.
- ノードグラフエディタコントロール
- ➕wieslawsoltes/Dock: A docking layout system.
- UniDockとは別のドックレイアウトコントロール
-
Avalonia.Controls.ProgressRing
- Avalonia Progress Ring とは別のプログレスリング
- AvaloniaQrCodeControl
-
Manufaktura.Controls.Avalonia
- 楽譜表示
- ✔GridExtra.Avalonia
- 便利なGrid拡張
- 元はFluentWPFの開発者のWPF/UWP向けライブラリ。移植
- Avalonia版は一部Avalonia公式プロパティをそのまま使うため注意
-
LoadingIndicators.Avalonia
- 9種類のローディングインジケータ
-
Zafiro.Avalonia
- This library offers common (and useful) features to AvaloniaUI based applications.
-
Baksteen.Avalonia.Tools.GridIndexer
- Gridのインデックス指定を
+1
とかできるライブラリ
- Gridのインデックス指定を
-
HeaderedScrollViewer
- いわゆるsticky scroll的な、標準の
ScrollViewer
にヘッダーを付与できるになるライブラリ
- いわゆるsticky scroll的な、標準の
-
Baksteen.Avalonia.Controls.AdornerAnchorPanel
- 子コントロールの相対位置でアイコンとかの位置指定ができるパネル
-
CassowaryNET.Avalonia
- レイアウトを自動計算してくれるパネルと計算ライブラリ
Theme & Control
-
AntDesign.Avalonia
- AntDesignのテーマ
- Romzetron.Avalonia
-
Ursa.Avalonia
- Semi.Avaloniaの開発者が作成しているUI Controls
- Navigation, TagInput, Button group, Timeline, Pagenation, IPv4Box
-
Macabresoft.AvaloniaEx
- Macabre2Dというゲームエンジンエディタで使われているコントロール&テーマ
- PleasantUI
MVVM
- ✔Epoxy
-
Mvvm.Navigation
- NavigationのコードをSource Generatorで自動生成するライブラリ
-
Stylet.Avalonia
- WPF/UWPのCaliburn.MicroにインスパイアされたMVVMライブラリ
MVU
Rx
SourceGenerator
-
AvaSourceGenerators
-
StyledProperty
やDirectProperties
を自動生成してくれるSG
-
-
DependencyPropertyGenerator
- 依存プロパティ、ルートevent、weak eventを自動生成してくれるSG
l8n/i18n
- ✔CodingSeb.Localization
- Ao.Lang.AvaloniaUI
- Echoes - TOML, SGベースの翻訳ライブラリ
DI / GenericHost
-
Hosting.Avaloniaui
- デスクトップアプリでGenericHostが使えるようになる
ライブラリサンプル - ちなみに公式のSampleのPRに手動でGenericHostに対応する例がある
- デスクトップアプリでGenericHostが使えるようになる
-
Stronginject
- コンパイル時にDIできるライブラリ
- wasm対応
- Avaloniaでの使用例
- コンパイル時にDIできるライブラリ
Other
-
NetSparkle
- 有名なアプリの更新ライブラリ(updater)
-
Baksteen.Avalonia.Blazor
- BlazorとAvaloniaのハイブリッドアプリのライブラリとデモ
- ✔Avalonia.Preferences
- クロスプラットフォーム対応のpreference(設定)ライブラリ
-
Clowd.Clipboard
- クリップボード管理ライブラリ
- ➕PupNet Deploy - Publish & Package for .NET
- クロスプラットホームパブリッシュツール
- AvanGardeの作者によるツールでzip/AppImage/InnoSetupなどにコンパイル&パブリッシュできるらしい
-
FontPicker
- フォント選択
-
WinForm2AvaloniaConverter
- WinFormをAvaloniaUIにコンバートするライブラリ
- ビジネスロジック部分は手動コピー前提
-
ValueConverters.Avalonia
- ValueConverters.NETのAvalonia移植版
-
ObservableCollections
- v2.2.0で対応
-
Breakpoints.Avalonia
- レスポンシブデザインでブレイクポイント(折り返し処理)指定ができるライブラリ
Avalonia XPFとは
- Avalonia社が提供する 企業向け商用サービス
- 既存のWPFアプリをクロスプラットフォーム移植してくれるというもの
- 技術的にはモバイルやWASM対応もできるけど、まずはDesktopむけ
- すでにアプリがある会社が利用するもので個人開発者は基本的に関係ない
- 内部的にAvaloinia UIの仕組みが使われているらしい
- インディーライセンス準備中(2024-05)
Avalonia UI | Avalonia XPF | |
---|---|---|
これはなに | UIフレームワーク | サービス |
価格 | 無料 | 有料 |
誰向け | 誰でも | 企業のみ |
日本語がわかる人がつくってるっぽいAvalonia関係
日本語情報がほとんどないAvaloniaだけど、この辺の作者さんに聞けば色々わかることがあるかも?
アプリ
ライブラリ
Avalonia v11情報
v11.1 Release
- ドキュメント更新がおいついてない(8/31)
https://github.com/AvaloniaUI/avalonia-docs/issues/384
v11.1 beta
-
HyperLinkButton
control が追加 - XAML中でWPFにもある
UpdateSourceTrigger
が使えるように - tvOS/AndroidTV/TizenTVのサポート。リモコン操作できるように
-
Launcher
APIが実装- フォルダ/ディレクトリを開く、関連付けアプリの起動が同じ記述でできるように
- 内部の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
porting guideに無い箇所
- file選択/saveダイアログ系は新apiに変更されている
- 結構別物
StorageProvider
に変わっているので注意 - https://docs.avaloniaui.net/docs/next/concepts/services/storage-provider
- 結構別物
-
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
公式のVSCode拡張。
-
プレビュー可能な公式VSCode拡張
- XAML補完とかもある
-
現時点の問題点
- v11.0.2以下でないとプレビューがうまくいかない
- 初回表示までにとても時間がかかる
-
クリック操作などは機能しない(一部直ってた)
プレビュー機能だけで言うと①や②の方が現時点では実用的。
XAMLプレビュー方法④ HotAvalonia
HotReloadを実現するライブラリ。
ドキュメントを読む限り、 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で持ってきたい所…
- なのでテーマ(Dark/Light)の切替は手動
<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を反映させる例があった。
DockItem
のHeaderを消す
<np:DockItem
ItemPresenterClasses="NoHeader"
/>
対象のDockItem
のItemPresenterClasses
属性でスタイルのクラスを設定する(例:NoHeader
)。
<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
なので混同しないように注意
using:YourNamespace.YourApp
が使える
namespaceにはWPFなどのXAMLと違ってxml namespaceにはusing:YourNamespace.YourApp
という記法が使える。C#のコード中とほぼ同じなのでラク
xmlns:ui="using:FluentAvalonia.UI.Controls"
※WPFと同じ記法clr-namespaceも使える
$parent
Bindingで親要素は- さらにその親は
$parent[n]
でどんどん階層を上がって行ける-
$parent
=$parent[0]
; 一つ目の親が0
-
- 詳細:Binding to an Ancestor
- 親要素のWindow:
$parent[Window]
$parent[ControlName]
Bindingで祖先のcontrolは -
$parent[Window]
でウィンドウ参照できる - もっと上は
$parent[ControlName; n]
でどんどん階層を上がって行ける
Bindingで別のコントロールのViewModelを参照するにはキャスト&再ビルド
-
((vm:MyUserControlViewModel)DataContext)
とする - ホットリロードだとエラーになる。要再ビルド
<Button Command="{Binding $parent[ItemsRepeater].((vm:MyUserControlViewModel)DataContext).DoItCommand}"
CommandParameter="{Binding ItemId}"/>
!
Bindingで否定は-
IsEnabled = "{Binding !#someElem.IsEnabled}"
みたいな反転ができる
<Element IsEnabled = "{Binding !#someElem.IsEnabled}" />
Task<T>
にbind)
非同期Bind(-
Task<T>
を返す非同期処理にBindできる- 返ってくるまでの内容を
FallbackValue
で指定できる - How to Bind to a Task Result
- 返ってくるまでの内容を
<TextBlock Text="{Binding MyAsyncText^, FallbackValue='Wait a second'}" />
"{Binding $parent.Bounds.Width}"
親要素と同じ幅を指定するのは -
$parent.Width
だとダメ。Bounds経由で。
【解決】Epoxy + Avalonia でCommandのバインドがうまくいかない時
- EpoxyにはEventBinderというCommandがバインドできなくてもバインドできる便利機能がある
<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だともう少し色々できたような…
Ancher/Pileを使う
解決策1:- VMでWindow.LoadedにバインドしたReadyコマンドの中とかで、
piledControl.SomeEventChanged += MyCommand()
する - HotAvaloniaのhotreloadと相性悪い場合にも使える
解決策2: あきらめてコードビハインド
- DragDrop.DropEventはPile/Anchor使っても上手くいかなかった
- 正直よく使うから何とかしたい…
- HotAvaloniaのhotreloadと相性悪い?
Fountain/Wellを使う
解決策:Epoxy1.15の-
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
に参照するとうまくゆく
- nugetの
- readme.md の xmlns が正しくない(WPFでも問題あり)
xmlns:loc="clr-namespace:Localization;assembly=Localization"
xmlns:loc="clr-namespace:CodingSeb.Localization;assembly=CodingSeb.Localization"
フォーラムとか
- 公式のgithub discussions
- 公式のTelegram
- StackOverflow
- 古い質問は公式の開発者チームが返答してくれている
- https://stackoverflow.com/questions/tagged/avaloniaui
- Reddit r/AvaloniaUI
- Discord
- DotNetEvolution #avalonia チャンネル
ゲーム用UIにAvalonia UIを使う
- Estragonia : Avalonia in Godot
- AvaloniaInside.MonoGame : Integration of MonoGame for Avalonia
- AvaStride : Renders Avalonia inside the Stride game engine.
- Unilonia : 開発停止
Demo
- UnrealEngine
関連
- Consolonia : ゲーム向けではなくてコンソール向け(TUI)
Avalonia UIドッキングライブラリ比較 (docking libs)
-
Dock.Avalonia
- 老舗ライブラリその1
- テーマ対応は自作する必要あり
- 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 | |
---|---|---|---|---|---|
★ | |||||
License | MIT | MIT | MIT | MIT | MIT |
nuget | - | - | |||
Framework | net6.0/8.0 | net8.0 | net8.0 | net7.0 | net8.0 |
外部テーマ反映 | x | x | ? | ✔ | x |
レイアウト保存復元 | ✔ | ✔ | ✔ | x | ? |
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
- FluentAvaloniaで指定できない種類も使える
- FluentAvaloniaようにnugetが分かれている
- アイコンライブラリ:fluentui-system-icons
使い方
- MarkupExtensionはAvaloniaでは動かない?
- 下の様にするとラク
<UserControl.Resources>
<ic:SymbolIconSource Symbol="ArrowLeft" x:Key="ArrowLeft" IsFilled="True" />
</UserControl.Resources>
IconSource="{StaticResource ArrowLeft}"
LucideAvalonia
- アイコンライブラリ:Lucide
- アイコン数:1509 (調査時点)
- v11.1以降限定
Projektanker.Icons.Avalonia
- アイコンライブラリ:FontAwesome 6 Free & Material Design Icons
使い方
FluentAvaloniaでIconSourceとして指定する場合、ThemeVariant対応に問題あり
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>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PublishAot>false</PublishAot>
<StripSymbols>false</StripSymbols>
</PropertyGroup>
trimmingオプション
NativeAOTはtrimが有効になるため、そのままだと必要以上に削除されて動かないことが良くある。
<PropertyGroup>
+ <TrimMode>partial</TrimMode>
</PropertyGroup>
<ItemGroup>
+ <TrimmerRootDescriptor Include="Avalonia.xml" />
</ItemGroup>
<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対応(ただしバグが多い)
ライブラリ
-
PublishAotCompressed
- UPXで追加圧縮をかけるライブラリ
テンプレ
参考ドキュメント
https://github.com/dotnet/runtime/blob/main/src/coreclr/nativeaot/docs/optimizing.md
Avalonia 非公式マニュアル
DropDownButton
A button with an added drop-down chevron to visually indicate it has a flyout with additional actions.
- なぜかマニュアルにない標準コントロール
- 分割されてない
SplitButton
みたいなコントロール -
Flyout
を入れるのにいい感じ
Avalonia.Controls/DropDownButton.cs
DataGrid
DataGridColumn.Width
DataGridColumn
の子クラスはWidth
(列の幅)プロパティに数値、*
, Auto
以外も指定できる。
-
SizeToCells
- セルの中身の幅に列の幅を合わせる
-
SizeToHeader
- セルのヘッダーの幅にに列の幅を合わせる
なぜかマニュアルに記載ない。
Notifications
- ContentCatalogにはあるけどマニュアルにない通知Control
- アプリウィンドウ内の通知
- 使い方がちょっと特殊
<!-- 通知を出したい所に書く -->
<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