@mitsuba_yu
Avalonia は
Casual Mac Apps
開発の銀の弾丸となりうるか。
• H.N. :蜜葉 優 [@mitsuba yu]
• silkyfeel Organizer
• Microsoft MVP for Windows Development
• Designer / Developer / Photographer
• Keynoteの表紙はいつも自分で撮影
• 最近はHasselbladのカメラを使うのが楽しい。
• http://c-mitsuba.hatenablog.com
Profile
• What is Avalonia
• Cross-Platform / XAML based Cross-Platform
• Avalonia
• Cross-Platform への 個人的スタンス
• Avalonia をとりあえず実行してみる
• 1本アプリをつくってみた
• tanzanite for Mac build in Avalonia
• まとめ
Agenda
• Avaloniaの現時点のバージョンは0.10.0です。
• Avaloniaは現バージョンをAlpha/Beta版とは言っていません。
• が、アップデート次第では本セッションの内容通りに動作しな
い場合があるかもしれません。
• 予めご理解ください。
Okotowari
• Avaloniaとはどんなものか。
• 誰向けの技術なのか。
• 他のCross-Platformとは、どう違うのか。
• Avaloniaでどこまでできるのか、どこまでやってみたのか。
• 個人的にはかなりイケてるのでご紹介。
Takeaway
What is Avalonia
6
7
• クロスプラットフォームとは、仕様が全く異なるハードウェア
またはOS上で、同じ仕様のものを動かすことが出来るプログ
ラムのこと。(WikiPedia 要約)
• 例えば、1つのプロジェクトでWindows、Mac、iOS、
Androidで動作するアプリが作れたりする夢のような話。
• Write Once Run Anywhere !!!!
• Ex:) Unity, Xamarin, React Native, Flutter, Cordova, Titanium
Cross-Platform
8
• クロスプラットフォームで、UIをXAMLで記述できるプラット
フォームたち。
• 最近メジャーなのはこの4つぐらい?
• Xamarin.Forms
• CSHTML5
• Uno Platform
• Avalonia
XAML based Cross-Platform
9
• Xamarinで選択できるプラットフォームの1つ。
• Monoで作られている。
• XamarinはそれぞれのプラットフォームのロジックコードをC#
で記述できる技術。
• Xamarin.Android => axml / c#
• Xamarin.iOS => Storyboard | Interface Builder / C#
Xamarin
10
Xamarin
(C#)
11
• そのXamarinのUI部分をXAMLで記述できるようにして、
Cross-Platform化したのがXamarin.Forms
• 記述できるXAMLはXAMLの形をしているけど、Xamarinで独自
て定義されたコントロールが多く、いわゆる方言がキツイ。
• Xamarinとしての推しが、Mobile Cross-Platformなので、
iOS/Androidの情報は多いが、Desktop環境での情報はかなり
少ない。
Xamarin.Forms
12
Xamarin.Forms
13
• 一応、Xamarin.MacもForms.Macも、存在はしている。
• が、ほとんど情報がないに等しい。
• Mac固有なUI定義には、結局Interface Builderが必要であった
りして、完璧にXAMLでラッピングされているわけではない。
• ので、Macのアプリをかんたんに作りたい!にはちょっと向い
てないな。(個人的に)
Xamarin.Forms
14
• C#/XAML for HTML5な技術。
• HTMLの代わりに、XAMLで。JSの代わりにC#で記述できる、
Web開発用のプラットフォーム
• Migrate existing Silverlight, WPF, UWP, and Xamarin apps to
the Web なんて謳ってる。
• 昔ちょっと触ってみた記憶では、なかなか良く出来てて面白い
(技術的に。)
• Webのみで、Cross-Platformか?と言われると違うかも?
CSHTML5
15
• 今イケイケのXAML based Cross-Platform。
• UWPをベースに設計され、Windows, WebAssembly, iOS, Mac,
Android, Linuxで動作する。
• サンプルコードも多いし、WinUIを取り込んだりイケイケ。
• 2018年5月にファーストリリースされている。
Uno Platform
16
• 実はXamarinの上で動作する。動作していた。
• 言い換えればよりWindows Appsな開発者の為に、
UWP風によりよく作られたXamarin.Forms。
ほぼUWPのノリでXAMLを記述できる。
• メインはモバイルプラットフォームだけど、一応MacApps開発
のドキュメントも少しずつ増えてきた。
Uno Platform
17
Uno Platform
• Monoから脱却した
Avalonia
18
19
• 正しくは、AvaloniaUI/Avalonia という名前。
• .NET5(.NET Core) + GTK3で作られている。
• 前述のと同じように、XAML/C#でアプリ開発が可能。
• 2015年から開発が進められている。
Avalonia
20
• UnoがUWPなら、AvaloniaはWPFベースの設計。
• ほぼWPFのノリでXAMLを記述できる。
• 他のCross-Platformに比べて技術スタックが薄い。
• 設計とコンセプトとして、他のCross-Platformに比べて、
Desktop上で動作するアプリのCross-Platformに強い。
Avalonia
21
• 正直あんまり信用してない。
• すべてのプラットフォームの最大公約数な機能しか使えない。
• 実装するプラットフォームが増えると、エラーだったり、落ち
たときに、どのレイヤーで問題があるのか切り分けが難しい。
• ex)WindowsとAndroidでは動くのに、iOSではなぜか動かん
• 結局それぞれのプラットフォームの知識が必要。
Cross-Platform
22
• WPFなら一瞬でできるのに、余所のプラットフォームで
”まともに”開発しようとすると、どうしていいか分かんない。
• そのために新しく言語・ツール覚えるのはめんどい。
• でもでも、簡単な便利ツールぐらいは作りたいよね。
• .o0( Silverlight OOB とか、その点めっちゃ良かった)
• やっぱり、書き慣れたスタイルで、いろんなプラットフォーム
のアプリが作れるのは、やっぱ良いよね。
Cross-Platform
23
• だから、Cross-Platformはしないけど、Cross-Platformな
ライブラリの都合の良い機能だけを使ってアプリを作ろう。
• StoryboardもInterfaceBuilderもSwiftも知らずにMacApps
を開発できる世界線は魅力的じゃない?
• っていうスタンス。
Cross-Platform
Avaloniaをとりあえず
実行してみる
24
25
• dotnet CLI
dotnet new -i Avalonia.Templates
• VS Code
• VS for Mac
• JetBrains Rider
• Visual Studio
• https://marketplace.visualstudio.com/items?
itemName=AvaloniaTeam.AvaloniaforVisualStudio
Develop
26
Project Template
27
• Avalonia Application
Project Template
28
• Avalonia MVVM Application
Project Template
29
• Avalonia MVVM Application
Project Template
30
• App.xaml.csでVMの初期化されてる
Project Template
31
• VSでF5で実行するだけ。
Exec onWindows
32
• Terminalからコマンドで実行する。
• csprojのあるフォルダで、dotnet run
• 対応IDEで実行
Exec on Mac
XAMLとデザイナーを軽くDEMO
33
O
34
35
• UWP製
• PCにインストールされてる
フォントを任意の文字で表示する。
• 任意のフォント名をコピー
• フォント一覧はSharpDXで取得
• 個人的に日頃デザイン作業はMac。
ホントはMacで欲しかった。
• Formsとかでやろうとしたけど、
思ってるUIが作れずに、イマイチ。
tanzanite - font selector tool -
36
tanzanite for Mac - font selector tool -
37
tanzanite for Mac - font selector tool -
• インストールされているフォント一覧を取得する。
• 任意の文字列を、全てのフォントで表示する。
• 文字色、背景色、フォントサイズを任意に設定する。
• 一覧からお気に入りフォントをピックアップしていく。
• お気に入りフォントのフォント名をコピーする。
• お気に入りを解除する。
38
tanzanite for Mac - font selector tool -
• インストールされているフォント一覧を取得する。
• System.Drawing.Text.InstalledFontCollection
• Macだと、corecompat.system.drawingが使える。
が、全てのフォントが取れるわけではない(謎
https://github.com/CoreCompat/CoreCompat
•
39
SkiaSharp
• Skia Graphics Library
• Googleが買収したOSSな2D Graphicsなライブラリ
• https://skia.org/
• SkiaSharp
• C#向けにラップしたライブラリ
• mono系プラットフォームでよく見かける。
• Avaloniaにも組み込まれている。
40
Binding Font Collection
• インストールされているフォント一覧を取得する。
• SkiaSharp.SKFontManager.Default.FontFamilies
• 今回はこれを採用。
• 実行環境にインストールされている全てのフォントと
フォントウェイトを取得できる。
41
Binding FontCollection
• 任意の文字列を、全てのフォントで表示する。
• 文字色、背景色、フォントサイズを任意に設定する。
• 普段どおり、XAMLとBindingで実現。
42
Binding FontCollection
• 任意の文字列を、全てのフォントで表示する。
43
Binding FontCollection
<ItemsControl Items="{Binding FontCollection}”
HorizontalAlignment="Stretch" VerticalAlignment=“Stretch">

<ItemsControl.Styles>
<Style Selector="WrapPanel">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property=“Width"
Value="{Binding Bounds.Width,ElementName=ScrollViewer}" />
</Style>
</ItemsControl.Styles>

<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Background="{Binding BackgroundColor}" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
• いつもどおり、IEnumerableをBinding
44
Binding FontCollection
• 文字色、背景色、フォントサイズを任意に設定する。
45
Binding Font Collection
• TextBlockにフォント名と、表示したい文字列をBinding
<Button Background="Transparent"
Command="{Binding DataContext.AddFavoriteListCommand,ElementName=Window}"
CommandParameter="{Binding}">
<Grid>
<StackPanel HorizontalAlignment="Stretch" Margin="12">
<TextBlock FontSize="16" Text="{Binding}"
Foreground="{Binding
DataContext.TargetFontColor.Value,ElementName=Window}"
Margin="0,0,0,2" />
<TextBlock FontSize="{Binding Value,ElementName=FontSize}"
Text="{Binding Text,ElementName=TargetText}"
Foreground="{Binding
                DataContext.TargetFontColor.Value,ElementName=Window}"
FontFamily="{Binding
             Converter={StaticResource StringToFontFamilyConverter}}" />
</StackPanel>
</Grid>
46
tanzanite for Mac - font selector tool -
• 一覧からお気に入りフォントをピックアップしていく。
• お気に入りを解除する。
47
Fav Font Item
• 選択フォントをお気に入りリストに追加するCommand
<Button Background="Transparent"
Command="{Binding DataContext.AddFavoriteListCommand,ElementName=Window}"
CommandParameter="{Binding}">
<Grid>
<StackPanel HorizontalAlignment="Stretch" Margin="12">
<TextBlock FontSize="16" Text="{Binding}"
Foreground="{Binding
DataContext.TargetFontColor.Value,ElementName=Window}"
Margin="0,0,0,2" />
<TextBlock FontSize="{Binding Value,ElementName=FontSize}"
Text="{Binding Text,ElementName=TargetText}"
Foreground="{Binding
                DataContext.TargetFontColor.Value,ElementName=Window}"
FontFamily="{Binding
             Converter={StaticResource StringToFontFamilyConverter}}" />
</StackPanel>
</Grid>
48
Fav Font Item
• お気に入りを解除する。
• Popupでコピーと解除メニューを表示
49
Fav Font Item (C#:VM)
AddFavoriteListCommand = new ReactiveCommand();
DeleteFavoriteListCommand = new ReactiveCommand();
CopyFontNameCommand = new ReactiveCommand();
var enumerable = SKFontManager.Default.FontFamilies.OrderBy(o => o);
FontCollection = new ObservableCollection<string>(enumerable);
FavoriteFontCollection = new ObservableCollection<string>();
AddFavoriteListCommand.Subscribe(o =>
{
var value = o.ToString();
if ((value != null) & FavoriteFontCollection.Contains(value)) return;
FavoriteFontCollection.Add(value);
});
DeleteFavoriteListCommand.Subscribe(o =>
{
var value = o.ToString();
if ((value != null) & FavoriteFontCollection.Contains(value)) FavoriteFontCollection.Remove(value);
});
CopyFontNameCommand.Subscribe(async o =>
{
var value = o.ToString();
if (value != null) await Application.Current.Clipboard.SetTextAsync(value);
});
50
Avalonia
• XAML系開発の経験があれば、本当に同じノリで書ける。
• ReactivePropertyも、Interactivityも使える。
• PrismとかMVVMhogehogeみたいなのも使えるらしい
(分厚いMVVMライブラリ嫌いなので、興味なし)
• 一方で、全くハマらなかった、という訳でもなかった。
51
• Style.Triggerがない。 -> Interactivity使え。
• 時々プロパティ名が変わっている。
• TextBoxで日本語が打てない。
• IMEの変換が表示されない。
• MacのCommand + Qで終了ができない。
• Macのメニューバーを作りたい。
• .App Packing
Point
52
• ActualWidth/Heightがなくなった。
• Control.Bounds.Width/Heightに変更。
• ItemsSourceがなくなった。
• ItemsにBinding可能になった。
• いくつかのPropertyの名前がWinRT準拠になった。
• PopupのIsLightDismissEnableとか。
• 冗長なプロパティ名が短く変更された。
• 完全にWPFのXAMLコピペすると、差分がでる。
• とはいえ、大した問題ではない。
Property
53
• TextBoxで日本語が打てない。
• TextBlockの日本語は正しく表示される。
• プロジェクトを作成したままだと、TextBoxの日本語が文字
化けする。
• 明示的にフォントを指定する。
• IMEの変換が表示されない。
• そういうものらしい。確定すれば表示される。
TextBox / IME
54
• FontFamilyに複数のフォントを指定できる。
• 順番に存在するフォントが使われる。
• Cross Platformらしい部分
• Windowに指定すれば、配下のコントロールのフォントが書き
換わる。TextBoxにだけ明示的にフォント指定しても良い。
<Window
Title="tanzanite for mac - font selector tool -"
x:Name=“Window"
FontFamily="Meiryo UI, Osaka">
TextBox / IME
55
• MacのCommand + Qで終了ができない。
• Macのメニューバーを作りたい。
• MacAppのショートカットはメニューバーで定義される。
• メニューバーを実装して、
初めてCommand + Qが使える。
Mac MenuBar
56
• しかも、他のと違って、XAMLで書ける!
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:tanzanite_for_mac"
Name="tanzanite - font selector tool -"
x:Class=“tanzanite_for_mac.App”>
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="About tanzanite for mac" IsEnabled="True"
Command="{Binding AboutCommand}" />
</NativeMenu>
</NativeMenu.Menu>
</Application>
Mac MenuBar
57
• App.xamlに共通メニューを、Windowには固有メニューを。
• ただし、Windowにも空のNativeMenuが必要。
• 初回起動時にメニューが表示されず、一度非アクティブにすると表示される。
• たぶんバグ。
• でも、ここをXAMLでBindableで書けるのが最高。
<Window xmlns="https://github.com/avaloniaui">
<NativeMenu.Menu>
<NativeMenu>
</NativeMenu>
</NativeMenu.Menu>
Mac MenuBar
58
• About MyApp
<NativeMenuItem
Header=
"About tanzanite for
mac”
Command=
“{Binding
AboutCommand}" />
Mac MenuBar
59
• https://avaloniaui.net/docs/packing/macOS
• ほぼここにあるままでOK
• アプリアイコンicnsは、基本的にはMacで作成する。
• Release用.App作成するには、この2つをcsprojのある場所で
コマンド実行すれば作られる。
dotnet restore -r osx-x64
dotnet msbuild -t:BundleApp -p:RuntimeIdentifier=osx-x64
-p:CFBundleDisplayName=MyBestThingEver -p:UseAppHost=true
.App Packing
60
• SkiaSharpで取得したフォント名だと、Windowsで動作させた
場合、日本語に正しくフォントが適用されない。
• TextBoxに日本語入力時に、ビープ音がなる(厳しい。
• レイアウト計算のコストが大きくて、うまくアニメーションさ
せれない。
Other Prombrem
61
Sum up
• Avaloniaを触ってみてから、やってみたことまでを紹介。
• WPFベースでUWPのコントロールのようなリッチさはない。
(でもFluentなUIテーマは存在する)
• ネイティブUIもXAMLで記述できる。
• プラットフォームとしては決して新しい部類ではない。
• ちょっと触ってみた系記事が日本語である。
しっかりした内容は、英語の公式ドキュメントが一番。
充実度も良い。
62
Sum up
• Style.Triggerが使えないのは痛い。コントロールのプロパティ
名が極稀に変わっている。IME周りがイケてない。
• でも、WPFと同じ知識同じ記述でMacApp開発ができるのは非
常に大きい。求めてたもの。
• 今回のtanzanite.appで大体120MBぐらいのサイズにはなる。
PCがターゲットなので、許せるかな。
• 個人的にイマ最推しのプラットフォーム。
• ぜひXAML系開発者には触ってみてもらいたい。
Avalonia for MacApps

Avalonia for MacApps