WPFを中心に書いています。Technologies。CanExecuteChanged;RelayCommand・DelegateCommandとはなにかDelegateCommandの簡単な利用方法ICommandとはなにかXAMLで発生した何らかの操作に基づき、処理を実行する「コマンド」を表します。ButtonのCommandプロパティにICommandの実態をバインドすることで、ボタンをクリックされた際に処理を実行する事が出来ます。メソッドと何が違うの?というと、以下の点が異なります。処理の実行可否を状態として持つ事ができ、また状態の変更を通知できる標準の仕組みではXAMLからメソッドの呼び出しはXAMLと同一クラス内のメソッド(コードビハインド)しか利用できないが、ICommandであればバインドが利用できる=別クラス(主にViewModel)の処理を呼び出すことができるといった特徴があります。この為、XAMLアーキテクチャで開発する上で、最も重要で基本的な概念の一つと言っても、まぁ誰も怒りはしないと思います。ICommandの概要さて、それではICommandをもう少し掘り下げてみてみましょう。}ICommandには3つのメンバが存在します。順番に説明していきます。parameter)コマンドで実行する処理の実体です。parameterにはXAML側でCommandParameterというのを指定すると渡されてきます。これはあくまで私個人の考えですが、ちゃんと必要な値がViewModelにバインドされていれば、どうしてもparameterで渡したいというケースはあまり多くなく、利用頻度は低いです。CommandParameterがXAML側で指定されていないと、nullが渡ってきます。parameter)コマンドが実行可能な状態かどうか判定します。コマンドがButtonのCommandプロパティにバインドされていた場合、この戻り値がfalseを返却すると、Buttonが非活性状態となります。CanExecuteChanged;コマンドの状態が変更されたことに伴い、CanExecuteの返す値が変わった場合、このイベントで変更があったことを通知します。イベントを受信した側は、改めてCanExecuteを実行し、状態の変更に対応します。入力フォームがあって、登録ボタンがあったとします。その際に、氏名が必須だった場合に、氏名が入力されていたら登録ボタンを有効化するといったことを、容易に実現することが可能になるわけです。慣れると便利ですよ!RelayCommand・DelegateCommandとはなにかさて、ここからが本題といえば本題です。ICommand、非常に便利かつ強力な仕組みなのですが、WPFでもXamarinでも標準では実装が存在しません。いって、毎度用途に合わせて実装するのも大変です。XamarinにはXamarin.Forms.Commandクラスという同様のデフォルト実装がありましたので、他のMVVMフレームワークを使わない場合はこちらを利用するとよいと思います。そこでRelayCommandまたはDelegateCommandの登場です。名前は異なりますが、実際にはほぼ同じものです。私が見た範囲では当初MSの文献にはRelayCommandという名称で出ていましたが、現在のPrismなどのMVVMフレームワークではDelegateCommandという名称で提供されています。本エントリー内ではDelegateCommandという名称で以後は統一しようと思います。DelegateCommandとは何者か?端的に言うと「コマンドの実行処理をActionとして、実行可否の判定をboolを返却するFuncを渡すことでインスタンス化できるICommand」です。通常はPrismとかMVVMLightとかLivetとか、何らかのMVVMフレームワークを使うと思いますが、どのフレームワークでも類する実装が含まれています。口頭では伝えにくいものがありますので、ここからは実際の使い方を見てもらいましょう。DelegateCommandの簡単な利用方法では、実際のDelegateCommandの利用方法を見ていきましょう。氏名と住所がある登録フォーム氏名が必須入力で、氏名が入力されないと登録ボタンは押せないというだけの、しょぼいアプリになります。実際の動作イメージは以下の通りです。WPFやXamarinのICommandを改めて整理するなお、今回のサンプルではPrismのDelegateCommandの実装を利用します。WPFで試される場合はNuGetから「Pris.WPF」を検索して追加してください。氏名・住所のテキストボックスがあって、その下に登録ボタンがあります。登録ボタンの下には、登録結果を表示するラベルがあります。見ると以下にバインディングが設定されているのが見て取れると思います。氏名TextBoxのTextプロパティ登録ButtonのCommandプロパティ結果LabelのContentプロパティポイントは登録ButtonのCommandプロパティにバインドされているコマンドです。住所テキストボックスは「在るだけ」ですが、氏名TextBoxからフォーカスアウトしないと、入力値がVMに渡らない為、一身上の都合で無駄に存在しています。ViewModelの方を見てみましょう。全部見ると大きいので、順番に。以下がポイントのDelegateCommandの部分です。DelegateCommandをプロパティとして公開し、コンストラクタの中でインスタンス化しています。一番目の引数はコマンドのExecuteメソッドを呼ばれた場合に呼び出されるActionです。実際に実行したい処理の内容を記述します。ここでは、結果ラベルにメッセージを表示しているだけですね。二番目の引数はコマンドのCanExecuteに該当するFuncを渡します。ここではコマンドが実行可能な状態かどうかをboolで返してあげます。ここではメソッドを渡していますが、もちろんラムダ式で記述しても問題ありません。二番目の引数は省略することも可能で、省略した場合、常に実行可能な状態となります。ViewModelでもう一つ重要な点が以下です。氏名のTextBoxにバインディングしているプロパティです。Nameプロパティが変更された場合に、先ほどのExecuteCommandに対して、RaiseCanExecuteChangedメソッドを呼び出すことによって、コマンドの実行可能状態が変わったことを通知してあげます。すると、対象のコマンドをバインドしているコントロールが、改めてコマンドのCanExecuteを呼び、実行可能状態を取得し、結果、Buttonが有効になります。言う分けで、今日はここまで。6.3がリリースされてからすでに2カ月。Commandさて、今回はCommand編です。(1)はてなブログをはじめよう!nuitsjpさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。