はじめに
Windows環境で開発可能なマルチプラットフォームGUI技術を解説してきた本連載も今回で最後になりました。最終回は前回の続きの予測気温表示アプリを解説し、アプリを完成させます。
対象読者
C#の基礎的な知識がある方を対象とします。C#の基本文法などの解説は割愛します。
予測気温表示アプリ──ボタンの追加とコマンドの実装
前回は、予測気温表示アプリのコンボボックス部分を解説しました。残りの処理を追加していきましょう。
ビューへボタン要素を追加する
まずはボタンを追加します。このボタンを押すことで、選択された県庁所在地の気温表示を行うようにします。
ビューのMainWindow.axamlの<ComboBox>の下に、UI要素のボタン<Button>を追加します。
<StackPanel HorizontalAlignment="Center"> ~中略~ </ComboBox> <Button HorizontalAlignment="Center" Margin="0,10,0,10" Width="120" Command="{Binding OnClickCommand}">24時間先の気温</Button> </StackPanel>
MVVMパターンでは、ボタンを押すなどのイベント処理は、コマンドというものにバインディングする形になります。Avalonia UIでは、WPF同様に、ボタンにコマンドをバインディングすることでイベント処理を行えます。<Button>のCommand属性に、ボタンを押した場合に呼び出される処理を記述します。ここでは、プロパティ名をOnClickCommandとしています。
MVVMパターンのコマンド処理
次にコマンドの実装なのですが、これがやや面倒です。WPF同様に、次のような流れになります。
- ICommandインターフェイスを実装したコマンドクラスを作成し、実行したい処理をExecuteメソッドに記述する。
- ビューモデルでコマンドクラスを生成し、そのインスタンスをプロパティで公開する。
このように、ビューやビューモデルからコマンド処理を切り離すことで、単体でテストが行えるようになります。
ただし、ボタンひとつのイベント処理でも、MVVMパターンではコード量が多くなりがちです。そのため、よりシンプルに記述できるオープンソースのMVVMパターン用のライブラリ(フレームワーク)が存在します。そのひとつに、ReactiveUIというものがあり、実はAvalonia UIのテンプレートプロジェクトにも含まれています。
ReactiveUIのReactiveCommandという、静的メソッドを定義したユーティリティクラスを使うと、コマンド処理がよりシンプルに記述できます。ビューモデルのMainWindowViewModelクラスに、次のようなコマンド処理を追加します。
public class MainWindowViewModel : ViewModelBase { public ReactiveCommand<Unit, Unit> OnClickCommand { get; } public MainWindowViewModel(string filePath) { ~中略~ OnClickCommand = ReactiveCommand.Create(OnClick); } private void OnClick() { // ボタンクリック時の処理 } }
ボタンがクリックされると、OnClickメソッドが実行されることになります。
ボタンクリック後の結果表示
次は、ボタンをクリックした後の処理で、テキストを表示するようにしてみましょう。まずは、テキスト表示をする<TextBlock>を、MainWindow.axamlに追加します。
<StackPanel HorizontalAlignment="Center"> ~中略~ </Button> <TextBlock HorizontalAlignment="Center" Text = "{Binding Result}" /> </StackPanel>
そして、バインディングしているResultプロパティを、MainWindowViewModelクラスに追加します。
public class MainWindowViewModel : ViewModelBase { // テキスト表示 public string Result { get; set; } = string.Empty; ~中略~ private void OnClick() { Result = "ボタンクリック"; } }
また、OnClickメソッドで、Resultプロパティを書き換えるようにします。これで、一度実行してみましょう。
ボタンをクリックしたら、文字が表示されましたか?
コントロールの書き換え通知
じつは、先ほどの処理では、ボタンをクリックしてもテキストが表示されません。確かにプロパティ自体は更新されるのですが、ウィンドウの<TextBlock>は、更新されないのです。
<TextBlock>を動的に更新するには、プロパティの更新時に、RaiseAndSetIfChangedメソッドを呼び出します。このメソッドにより、プロパティの内容が変更されている場合は、画面が更新されていることが通知され、画面の書き換え処理が実行されます。
private string result = string.Empty; public string Result { get => result; set => this.RaiseAndSetIfChanged(ref result, value); }
ボタンをクリックすると、次のように表示されるはずです。
今度は、選択された県庁所在地を表示してみましょう。MainWindowViewModelクラスのOnClickメソッドを次のように変更します。
private void OnClick() { if (Capitalpoint.Name != string.Empty) { Result = Capitalpoint.Name; } else { Result = "県庁所在地を選択してください "; } }
コンボボックスから県庁所在地を選択して、その後ボタンをクリックすると、選択された県庁所在地が表示されます。
コンボボックスで選択した値は、Capitalpointプロパティを通じて参照できます。したがって、Capitalpoint.nameをResultプロパティに代入すると、画面に表示されるというわけです。