SHOEISHA iD

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

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

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

特集記事

C++/CX: Windows 8 ストアアプリことはじめ (2)

データ・バインディングのキホン

Model→View

 まずは簡単なModel→Viewから。CounterViewModel.hを示します:

list-6
// CounterViewModel.h
#pragma once
#include "Common/BindableBase.h"   // Common::BindableBase
#include "CounterLib/CounterLib.h" // Counterlib::Counter
#include <memory> // std::uniqur_ptr

namespace CounterApp {

  [Windows::UI::Xaml::Data::Bindable]
  public ref class CounterViewModel sealed : Common::BindableBase {
  public:
    CounterViewModel();

    // properties
    property int Count { int get(); }

    void increment();
    void decrement();

  private:
    std::unique_ptr<CounterLib::Counter> counter_;
  };

}
  • アトリビュート:[Windows::UI::Xaml::Data::Bindable]をつけること
  • Common::BindableBaseから導出すること

がここでの定石です。

 int型のプロパティ:Countを定義しました。Viewがこのプロパティを読み取ってTextBlockに表示するよう仕向けます。

 CounterViewmodel.cppはこんな感じ:

list-7
// CounterViewModel.cpp
#include "pch.h"
#include "CounterViewModel.h"

using namespace Platform;
using namespace Windows::UI::Xaml::Input;

namespace CounterApp {

  CounterViewModel::CounterViewModel() : counter_(new CounterLib::DefaultCounter(0)) {}

  // properties
  int CounterViewModel::Count::get() { return counter_->get(); }

  void CounterViewModel::increment() {
    counter_->increment();
    OnPropertyChanged(L"Count");
  }

  void CounterViewModel::decrement() {
    counter_->decrement();
    OnPropertyChanged(L"Count");
  }

}

 increment()/decrement()内でOnPropertyChanged(L"Count")することで「Countプロパティが変更された」ことをViewに伝え、Viewはそれを契機にCountを読み取ります。ViewすなわちMainPage.xamlの変更点は1つだけ、<TextBlock>要素にText="{Binding Count}"を追加し、TextBlockのTextをCountプロパティに紐づけます。

fig-2 TextBlockのTextをCountプロパティに紐づけ
screen-shot

 MainPage.xamlのコード・ビハインドはこのようになります。

list-8
// MainPage.xaml.h (step-1)
// MainPage クラスの宣言
//

#pragma once

#include "Common\LayoutAwarePage.h" // 生成されたヘッダーによって要求されます
#include "MainPage.g.h"
#include "CounterViewModel.h" // 追加

namespace CounterApp
{
    /// <summary>
    /// 多くのアプリケーションに共通の特性を指定する基本ページ。
    /// </summary>
    public ref class MainPage sealed
    {
    public:
        MainPage();

    protected:
        virtual void LoadState(Platform::Object^ navigationParameter,
                               Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
        virtual void SaveState(Windows::Foundation::Collections::IMap<Platform::String^, Platform::Object^>^ pageState) override;
    private:
        void btnInc_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
        void btnDec_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
        CounterViewModel model_; // 追加
    };
}
list-9
// MainPage.xaml.cpp (step-1)
// MainPage クラスの実装
...

MainPage::MainPage() 
{
    InitializeComponent();
    CounterPage->DataContext = %model_; // 追加
}

...

void CounterApp::MainPage::btnInc_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
  model_.increment();
}

void CounterApp::MainPage::btnDec_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
  model_.decrement();
}

 コンストラクタでバインドする相手(プロパティを読み出す先)となるCounterViewModelを設定しています。ボタンのイベント・ハンドラからはTextBlockのTextを更新する処理が消え、単にincrement/decrementするだけになりました。

次のページ
View→Model

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

特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7130 2013/05/14 14:10

イベント

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

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

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

メールバックナンバー