SHOEISHA iD

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

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

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

特集記事

「ペライチ」からはじめよう
~C++/CX Windows 8.1ストアアプリことはじめ

step2:ViewとModelの仲介役

 アプリの外観MainPage.xaml(View)を基盤となるデータ:Counter(Model)から切り離し、その両者を結び付ける仲介役となるViewModelを作ります。ひな型がこちら、ファイル名/名前空間/クラス名は適宜書き換えて使ってください(Visual Studio 2012ではCommonフォルダに生成されたCommon::BindableBaseを導出すればよかったのですが、2013ではCommon::BindableBaseが生成されません)。

CounterViewModel.h
#pragma once

namespace CounterApp {

    namespace cx {
      namespace data  = Windows::UI::Xaml::Data;
    }

    [Windows::UI::Xaml::Data::Bindable]
    public ref class CounterViewModel sealed : cx::data::INotifyPropertyChanged {
    public:
        CounterViewModel();

        virtual event cx::data::PropertyChangedEventHandler^ PropertyChanged;
    };

}
CounterViewModel.cpp
#include "pch.h"
#include "CounterViewModel.h"

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

namespace CounterApp {

    CounterViewModel::CounterViewModel() {
    }

}

 これを起点にCounterViewModelを作っていきましょう。ViewModelの大きな役割の一つはView(ここではMainPage.xaml)が必要とするデータをプロパティの形で提供することです。CounterAppアプリでViewが必要としているのはもちろんカウント値(つまりCounterLib::get()が返す値)です。こんなコードになるでしょう。

CounterViewModel.h
#pragma once

#include "CounterLib/CounterLib.h"

namespace CounterApp {

    namespace cx {
      namespace data  = Windows::UI::Xaml::Data;
    }

    [Windows::UI::Xaml::Data::Bindable]
    public ref class CounterViewModel sealed : cx::data::INotifyPropertyChanged{
    public:
        CounterViewModel();

        virtual event cx::data::PropertyChangedEventHandler^ PropertyChanged;
        property int Count { int get(); }

    private:
        CounterLib::Counter counter_;    
    };

}
CounterViewModel.cpp
#include "pch.h"
#include "CounterViewModel.h"

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

namespace CounterApp {

    CounterViewModel::CounterViewModel() {
    }

    // property Count
    int  CounterViewModel::Count::get() { return counter_.get(); }

}

 ご覧のとおり、int型のプロパティ:Countがcounter_.get()を返すように仕組んでいます。このプロパティ値がMainPageにあるTextBlockのTextに反映されればいい。以下がMainPage.xaml(の抜粋)です。

MainPage.xaml
<Page .... />

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">C++/CX Windows 8.1 ストアアプリことはじめ</x:String>
        <local:CounterViewModel x:Key="ViewModel"/> <!-- [1] -->
    </Page.Resources>

    <Grid ...

        <!-- 新たに追加: ここから -->
        <Grid Grid.Row="1" DataContext="{StaticResource ViewModel}"> <!-- [2] -->
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid Grid.Column="1">
                <!-- このGridの中にコントロールを配置します -->
                <TextBlock Text="{Binding Count}" ... /> <!-- [3] -->
                <Button Command="{Binding Increment}" .../>
                <Button Command="{Binding Decrement}" .../>
            </Grid>
        </Grid>
        <!-- 新たに追加: ここまで -->

    </Grid>
</Page>

 キモとなるのは3つ、

  1. CounterViewModelに名前を付けてPage.Resourcesに追加すること
  2. Gridの DataContextに1.で追加したCounterViewModelをセットすること
  3. TextBlockのTextアトリビュートにCountプロパティをバインドすること

 これだけです(ついでに2つのButtonのCommandにもなにやらバインドされていますが、これについては後述)。TextBlockにつける名前(x:Name="...")すら省略し、プロパティだけでViewとViewModelとをつないでいます。

 MainPageのコードビハインドに手を加えるのは一か所だけ。MainPage.xaml.hに#include「CounterViewModel.h」を追加します。コードビハインドはもはやCounterViewModelを必要としないのでできればやりたくはないのですが、正しいコード生成のための「おまじない」ってことでカンベンしてください。

 ビルドするとエディタ上のMainPage.xamlに大きな0が現れるはず。TextBoxからCounterViewModelのCountプロパティを介してCounter::get()までがつながった証です。

次のページ
step3:Button-clickをバインドする

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

特集記事連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7506 2013/12/17 14:00

イベント

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

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

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

メールバックナンバー