基本のMVVMアプリ
まずは、テンプレートプロジェクトを使って基本となるMVVMアプリを作成してみましょう。
最初のプロジェクト作成
Visual StudioでAvalonia UIを利用するには、拡張機能を追加するのが手軽です。Visual Studioのメインメニュー[拡張機能]ー[拡張機能の管理]を開き、Avaloniaで検索します。すると次のような拡張機能が見つかりますので、「Avalonia for Visual Studio 2022」をダウンロードしてインストールします。
拡張機能の「Avalonia for Visual Studio 2022」をインストールすると、プロジェクトテンプレートに次のようなテンプレートが追加されます。
テンプレートの名称どおり「MVVM」を含むものがMVVMパターンでのプロジェクトで、もう一方がMVVMパターンではないシンプルなプロジェクトになります。2つのテンプレートでの大きな違いは、ViewModel関連のクラスがあるかないかになります。
今回はMVVMパターンを使ったアプリを解説しますので、「Avalonia MVVM Application」を選んで新規プロジェクトを作成しましょう。
動作の確認
プロジェクト名や場所などを適宜設定すると、プロジェクトが作成されます。このままビルドして起動してみましょう。
ウィンドウに文字列を表示するだけの、お決まりのHelloWorldアプリが起動するはずです。
プロジェクトのフォルダー構成
新規作成されたプロジェクトのファイル/フォルダー構成は、次のようになっています。
\Assets ----- アイコンなどのリソースファイル \Models ----- モデルクラス用(空フォルダー) \ViewModels ----- ビューモデルクラス \Views ----- ビュークラス App.axaml ----- Applicationクラスの定義 Program.cs ----- エントリーポイントとなるクラス定義 ViewLocator.cs ----- ViewModelとViewを関連づけるクラス
Viewsフォルダーには、メイン画面となるMainWindow.axaml、ViewModelsフォルダーには、メイン画面のViewModelとなるクラス定義、MainWindowViewModel.csが含まれています。
Avalonia UIでは、画面定義はXAMLベースなのですが、XAMLファイルの拡張子は標準ではWPFのような.xamlではなく「.axaml」となっています。文法的にはWPFのXAMLと違いはありませんが、UI要素の属性などはWPFとは微妙に異なっている部分もあります。
データバインディング
ビューとなるMainWindow.axamlは次のようになっています。UI要素の定義は1つだけです。
<Window xmlns="https://github.com/avaloniaui" ~中略~ <TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Window>
UI要素の<TextBlock>は、テキストを表示するラベルのようなものです。HorizontalAlignment、VerticalAlignment属性で、上下左右の位置を指定しています。サンプルではCenterとなっているので、ウィンドウの中央に表示されることになります。
<TextBlock>のText属性で、表示する文字列を指定します。ただし、直接文字列を記述していません。ここでは次のような書式で、ビューモデルであるMainWindowViewModelクラスのGreetingプロパティにバインディングしています。
"{Binding プロパティ名}"
MainWindowViewModelクラスのほうは、Greetingプロパティの定義のみとなっています。
~中略~ public class MainWindowViewModel : ViewModelBase { public string Greeting => "Welcome to Avalonia!"; }
MainWindowViewModelクラスの初期化時に、Greetingプロパティに文字列を設定しています。アプリが起動してウインドウが生成されると、この文字列が表示されます。このようにプロパティを参照するだけ(OneWay)のバインディングがデフォルトです。
単なる表示ではなくテキスト入力などのUI要素は、双方向のバインディングが必要です。その場合XAML定義では、Mode属性にTwoWayと指定します。
"{Binding プロパティ名, Mode=TwoWay}"