SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Silverlight 4で作る新しいRIAアプリケーション

MVVMによるSilverlightアプリケーションの開発(その1)

Silverlight4で作る新しいRIAアプリケーション(6)


ダウンロード sample.zip (178.1 KB)

コマンドバインディング

 コマンドバインディングは、コマンドの実装ロジックをビューモデルのプロパティとして公開することで、コードビハインドからイベントハンドラを排除し、意味的なコマンドをビューから直接指定する仕組みです。WPFにはもともと存在していましたが、Silverlightではバージョン4で新たに追加されました。

 Silverlightでコマンドを利用したい場合には、次の手順でコマンドを作成し、ビューにバインドする必要があります。

  1. ICommandインターフェースを実装したコマンドを作成する
  2. ViewModelのプロパティとしてコマンドを公開する
  3. ICommandSourceインターフェースを実装したクラスにバインドする

 1つずつ見ていきましょう。

1. ICommandインターフェースを実装したコマンドを作成する

 コマンドバインディングするコマンドは、ICommandインターフェースを実装している必要があります。例えば検索を行うコマンドを実装する場合には、次の表のメソッドやプロパティを実装する必要があります。

表 ICommandインターフェースで実装すべき項目
No 実装する項目 説明
1 CanExecuteChanged 実行状態が変更された場合に発生するイベントハンドラ
2 CanExecute 検索を行っていいか判断するメソッド
3 Execute コマンドの実体を記述するメソッド

 ICommandを実装したコマンドオブジェクトの実装例をリスト3に示します。

リスト3 コマンドオブジェクトの実装例(Find書籍Command.cs)
public class Find書籍Command : ICommand
{
    public Find書籍Command() { }
    /// <summary>
    /// 実行状態が変更された場合に発生するイベントハンドラ
    /// </summary>
    public event EventHandler CanExecuteChanged;

    /// <summary>
    /// CanExecuteChangedイベントを発生させ、CanExecuteメソッドを実行します。
    /// </summary>
    public void RaiseCanExecuteChanged()
    {
        var handler = CanExecuteChanged;
        if (handler != null)
            handler(this, EventArgs.Empty);
    }

    /// <summary>
    /// コマンドが実行可能か調査するメソッド
    /// 例えばボタンにコマンドがバインドされた場合、このメソッドの返却値によってボタンのIsEnableプロパティが変化します。
    /// </summary>
    public bool CanExecute(object parameter)
    {
        var item = parameter as MainPageViewModel;
        if (item == null)
            return true ;
        return ! item.HasChange;
    }

    /// <summary>
    /// コマンドの実体を記述するメソッド
    /// </summary>
    public void Execute(object parameter)
    {
        var item = (MainPageViewModel)parameter;

        // WCFサービスの検索メソッドを呼び出し結果をビューモデルに格納する。
        var proxy = new 書籍管理ServiceProxy.書籍管理ServiceClient();
        proxy.Find書籍ByIdCompleted += (source, e) =>
        {
            if (e.Error != null)
                MessageBox.Show(e.Error.Message);

            item.Id = e.Result.Id;
            item.タイトル = e.Result.タイトル;
            item.登録日 = e.Result.登録日;
            item.ISBN = e.Result.ISBN;
            item.TimeStamp = e.Result.TimeStamp;
            item.HasChange = false;
        };

        int id;
        if (!int.TryParse(item.SearchId, out id))
            return;
        proxy.Find書籍ByIdAsync(id);
    }
}

 画面に表示されたボタンは、状況によって実行されてほしくない場合があります。

 例えば、値がロードされていないのに更新ボタンが実行されるのはおかしかったり、更新途中なのに再度検索を実行してほしくないといった場合です。

 ICommandインターフェースでは、バインドされたコントロールはCanExecuteメソッドで現在自分は実行してよいのかを確認します。コマンドの実行が可能になったら、プログラム側でCanExecuteChangedイベントを呼び出すことで、コントロールが再度CanExecuteメソッドを通じて状態を確認します。

 今回はRaiseCanExecuteChangedメソッドを公開することで、ビューモデル側からCanExecuteChangedイベントを実行できるようにしています。

 Executeメソッドは、そのコマンドで実行した処理の実体です。ここでは、引数に与えられたViewModelのIdプロパティをもとに、サーバ側のWCFサービスを呼び出し検索を実行しています。

2. ViewModelのプロパティとしてコマンドを公開する

 コマンドを作成したので、ビューモデル側にリスト4のようなプロパティを用意し、コマンドを公開します。

リスト4 コマンドの公開(MainPageViewModel.cs)
public Find書籍Command _検索Command;
public Find書籍Command 検索Command
{
    get { 
        if (_検索Command == null)
            _検索Command = new Find書籍Command();
        return _検索Command;
    }
}

3. ICommandSourceインターフェースを実装したクラスにバインドする

 コマンドをバインディングできるのは、ICommandSourceインターフェースを実装したコントロールだけです。Silverlight 4では、次のコントロールが標準でコマンドバインディングを利用できます。

  • Button
  • MenuItem
  • HyperLink

 この他のコントロールや、クリックイベント以外でコマンドバインディングを利用したい場合は、ICommandSourceインターフェースを実装したコントロールを作成するか、後述するビヘイビアを利用します。

 ここまでで、書籍検索を行うサンプルが完成しました。

 Visual Studioでサンプルを実行してみてください。添付したサンプルには更新や削除といった機能も追加しているので、気になる方はダウンロードしてみてください。

まとめ

 前編では、MVVMパターンとは何か、SilverlightでどのようにMVVMパターンを実装すればよいかといった基本的な部分に触れました。次回(後編)では、MVVMパターンをもっと簡単に実装する方法、ツールについて解説していきます。

参考文献

修正履歴

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Silverlight 4で作る新しいRIAアプリケーション連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト かるあ (杉山 洋一)(カルア(スギヤマ ヨウイチ))

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5699 2011/02/22 00:07

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー