SHOEISHA iD

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

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

速習 Windowsストアアプリケーション

分割アプリケーションとグリッドアプリケーション

速習 Windowsストアアプリケーション 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

SplitPage.xaml

 2つ目のページクラス「SplitPage.xaml」は、ItemsPageからグループ選択時に遷移するページです。

SplitPageに遷移するコード(ItemsPage.xaml.cs)
void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
    // 適切な移動先のページに移動し、新しいページを構成します。
    // このとき、必要な情報をナビゲーション パラメーターとして渡します
    var groupId = ((SampleDataGroup)e.ClickedItem).UniqueId;
    this.Frame.Navigate(typeof(SplitPage), groupId);
}

 「SplitPage.xaml」は画面左側にListViewを配置してアイテムの一覧を表示、右側にListViewで選択したアイテムの詳細を表示しています。

データバインディング

 ItemsPage、SplitPageそれぞれのページに表示しているデータは、「データバインディング」という仕組みを用いて表示されています。

 「データバインディング」とは、XAMLのプロパティ(例えばTextBlockのTextプロパティ)とコードビハインドのC#のクラスのプロパティを紐づけて、一方向ないし双方向で値を連動させる仕組みです。

データバインディング
データバインディング

 XAML側のバインド可能なプロパティは依存関係プロパティのみです。

 データバインディングを利用する場合、データ側はINotifyPropertyChangedインターフェースを実装する必要がありますが、BindableBaseクラスはINotifyPropertyChangedを実装してプロパティの変更をView側に伝えるOnPropertyChangedメソッドと、プロパティ変更のサポートメソッドのSetPropertyを備えています。

BindableBaseクラスのコード(一部)
public abstract class BindableBase : INotifyPropertyChanged
{
    /// <summary>
    /// プロパティの変更を通知するためのマルチキャスト イベント。
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// プロパティがすでに目的の値と一致しているかどうかを確認します。必要な場合のみ、
    /// プロパティを設定し、リスナーに通知します。
    /// </summary>
    /// <typeparam name="T">プロパティの型。</typeparam>
    /// <param name="storage">get アクセス操作子と set アクセス操作子両方を使用したプロパティへの参照。</param>
    /// <param name="value">プロパティに必要な値。</param>
    /// <param name="propertyName">リスナーに通知するために使用するプロパティの名前。
    /// この値は省略可能で、
    /// CallerMemberName をサポートするコンパイラから呼び出す場合に自動的に指定できます。</param>
    /// <returns>値が変更された場合は true、既存の値が目的の値に一致した場合は
    /// false です。</returns>
    protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
    {
        if (object.Equals(storage, value)) return false;

        storage = value;
        this.OnPropertyChanged(propertyName);
        return true;
    }

 実際にSplitPageでのデータバインディングのコードを見ながら、説明していきます。

 「SplitPage.xaml」側ではDataContextプロパティにデータバインディングの指定をしています。

SplitPage.xamlのデータバインド
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"

 DefaultViewModelというプロパティをデータバインドする対象に指定しています。コードビハインド(C#)側では、

SplitPage.xaml.csのDefaultViewModelプロパティ
var group = SampleDataSource.GetGroup((String)navigationParameter);
this.DefaultViewModel["Group"] = group;
this.DefaultViewModel["Items"] = group.Items;

「Group」と「Items」というキーに値をセットしています。このDefaultViewModelプロパティも、LayoutAwarePageで定義されているものです。

 再び「SplitPage.xaml」に戻ります。

SplitPage.xamlのリソース定義
<Page.Resources>

    <!-- このページで表示されるアイテムのコレクション -->
    <CollectionViewSource
        x:Name="itemsViewSource"
        Source="{Binding Items}"
        d:Source="{Binding AllGroups[0].Items, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/>
</Page.Resources>

 「itemsViewSource」という名前(x:NAME)で、ItemsプロパティをCollectionViewSourceとして宣言しています。これはGridViewコントロールなどのバインド対象のソースとして、DefaultViewModelのItemsを利用可能にするという意味です。DefaultViewModelのItemsは、先ほどSplitPage.xaml.csで見た以下の行のプロパティのことです。

SplitPage.xaml.csのDefaultViewModelのItems
this.DefaultViewModel["Items"] = group.Items;

 ListViewでは、以下のようにitemsViewSourceを利用しています。

ListViewコントロールのItemsSource
<ListView
    x:Name="itemListView"
    AutomationProperties.AutomationId="ItemsListView"
    AutomationProperties.Name="Items"
    TabIndex="1"
    Grid.Row="1"
    Margin="-10,-10,0,0"
    Padding="120,0,0,60"
    ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
    IsSwipeEnabled="False"
    SelectionChanged="ItemListView_SelectionChanged"
    ItemTemplate="{StaticResource Standard130ItemTemplate}"/>

 ItemsSourceに先ほどのitemsViewSourceを指定しています。これでListViewにC#のコレクションをバインドすることができました。

コンバーター

 データバインディングする際に直接値を表示せずに加工したい場合があります。

 たとえばコードビハインド側では300というint型の値ですが、Viewに表示する際には300円と円マークをつけたい場合です。

 このような変換にコンバーターを利用します。

コンバーター
コンバーター

コントロールtoコントロールのデータバインディング

 SplitPageでは、ListViewのリストから選択したアイテムの詳細データを右側に表示しています。この選択したアイテムを表示するという処理も、データバインディングを利用しています。

 先ほどはListViewコントロールとコードビハインド(C#)のバインディングでしたが、今度はコントロールとコントロールのバインディングです。

ListViewの選択したアイテムを詳細表示する仕組み
<!-- 選択したアイテムの詳細 -->
<ScrollViewer
    x:Name="itemDetail"
    AutomationProperties.AutomationId="ItemDetailScrollViewer"
    Grid.Column="1"
    Grid.RowSpan="2"
    Padding="70,0,120,0"
    DataContext="{Binding SelectedItem, ElementName=itemListView}"

 これはitemListViewというx:Name属性のついたListViewコントロールの選択されたアイテムをバインドするという意味です。

 DataContextの値は、コントロールの入れ子になった下位コントロールにも伝播しますので、ScrollViewerで囲まれたコントロールはすべてitemListViewのSelectedItemとバインディング可能です。

次のページ
グリッドアプリケーション

修正履歴

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
速習 Windowsストアアプリケーション連載記事一覧

もっと読む

この記事の著者

西村 誠(ニシムラ マコト)

 Microsoft MVP Windows Platform Development。 Flash、PHPの開発経験もあり国産ECサイト構築フレームワーク「EC-CUBE」の公式エバンジェリストでもある。 ブログ:眠るシーラカンスと水底のプログラマー 著書:基礎から学ぶ Windowsストアアプリ開発

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6889 2012/12/03 17:35

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング