最新のアプリ

Windows ストア アプリのハブ プロジェクトと Hub コントロールの概要

Rachel Appel

Rachel AppelVisual Studio を使用した Windows 向け開発の際は、組み込みのプロジェクト テンプレートから開始することをお勧めします。Windows ストア アプリ (またはマイクロソフト製品) 向けの開発が初めての方は、テンプレートを学習ツールとして利用できます。今回のコラムでは、Hub コントロールについて、ハブ プロジェクト テンプレートの観点から説明します。また、HTML アプリ用と XAML アプリ用の両方のハブ プロジェクトと Hub コントロールについて、知っておく必要があるすべての重要事項も紹介します。

特にハブ プロジェクトを使用すると、最新のユーザー エクスペリエンス (UX) を採用しながら大量のコンテンツをユーザーに提供できます。これは、アプリに表示される大量のデータにユーザーが圧迫感を受けないよう、アプリのコンテンツを HubSection と呼ばれる部分に分割できるためです。これは個人的な意見ですが、ハブ プロジェクトは、すべての Windows ストア アプリ テンプレートの中で最も見栄えが良いテンプレートだと思っています。コンテンツのレイアウトは、わかりやすいセクションごとにまとまっています。好みのコンテンツをハブで最も目立つ "メイン" セクションに表示できる一方、残りのコンテンツ項目にはグループ単位で簡単にアクセスできます。

もちろん、テンプレートの使用は必須ではなく、空のプロジェクトからも開発を開始できます。しかし多くの開発者にとっては、テンプレートに基づいてカスタマイズや拡張を行う方が、コードがあらかじめ用意されているのではるかに簡単です。

ハブ プロジェクト テンプレート

Visual Studio 2013 には、HTML 用と XAML 用の両方のハブ プロジェクト テンプレートが用意されています。ハブ テンプレートを使用して新しい HTML プロジェクトを作成すると、css フォルダー、images フォルダー、js フォルダーなど、見慣れたプロジェクト フォルダーがいくつか作成されます。通常のフォルダーに加えて、pages\hub、pages\item、および pages\section というハブ固有のフォルダーもあります。お察しのとおり、これらの各フォルダーには、アプリのハブ、項目、およびセクションに対応するファイルが含まれています。プロジェクト ルートには、パッケージ マニフェストのファイルと default.html があります。default.html はアプリの出発点です。default.js を読み込んで、アプリやライフサイクル管理に関連した機能を実行します。default.html には、\js\default.js ファイルの参照だけでなく、サンプル データを含んでいる \js\data.js の参照や、ナビゲーションを実行する \js\navigator.js の参照も含まれています。ナビゲーションについて復習するには、2013 年 8 月号のこのコラム「Windows ストア アプリでのナビゲーションの必須要素」(msdn.microsoft.com/magazine/dn342878) を参照してください。端的に言えば、ハブ プロジェクト テンプレートは他のテンプレート同様に、見栄えが良い最新のアプリを公開する簡単な手段です。

もちろん、ハブ プロジェクトで最も重要な要素は Hub コントロールです。JavaScript 用 Windows ライブラリ (WinJS) を使用して構築したアプリでは default.html からプロジェクトの実行を開始しますが、いったん default.html を読み込んだらすぐに hub.html ファイルに遷移します。hub.html は Hub コントロールを含んでいて、\pages\hub ディレクトリにあります。Hub コントロールは、四角形を単調にまとめただけではない、最新レイアウトの作成に使用するコントロールです。Hub コントロールと非同期のデータ取得を組み合わせると、大量のデータや別々のグループに分かれたデータを体系的かつ洗練された方法で提供できます。

ハブ テンプレートには、ハブ (階層) ナビゲーション パターンが実装されています。このため、ユーザーは出発点 (ハブ ページ) から特定のセクションの全メンバーを含むページに移動することも、ハブ ページから個別の項目に移動することもできます。また、ハブ テンプレートにはセクション ページから項目ページへのナビゲーションも含まれています。ハブ テンプレートに含まれているナビゲーション コードはセクション 3 とそのグループや項目の間のナビゲーションだけですが (図 1 参照)、開発するアプリで理にかなっていれば、他のセクションにも ListView コントロールや Repeater コントロールを使用して同様のナビゲーションを実装できます。図 1 に、サンプル データを使用した既定のハブ アプリを実行しているようすを示します。

The Hub Control at Run Time for Both HTML and XAML Apps
The Hub Control at Run Time for Both HTML and XAML Apps
The Hub Control at Run Time for Both HTML and XAML Apps
図 1 HTML アプリと XAML アプリの両方に使用できる Hub コントロールを実行したようす

Windows の刷新に伴って、コンテンツ優先という概念が導入されましたが、ご覧のとおりハブ テンプレートはまさにこの概念を体現しています。

XAML のハブ テンプレート プロジェクトも、概念上は HTML テンプレートと同様に機能します。ハブをメインの出発点として使用し、そこからセクションや詳細項目に移動できます。もちろん、実装は異なっています。フォルダー構造を調査すると実装の違いを確認できますが、XAML テンプレートには Assets、Common、DataModel、および Strings というディレクトリがあります。これらのフォルダーには、ご想像どおりの項目が含まれています (グラフィックなどの資産、DataModel フォルダー内のデータ、Strings フォルダー内のローカライズされた文字列など)。プロジェクトのルートには、アプリの実行に必要な次の機能ファイルがあります。

  • App.xaml/.cs: XAML 用の default.html と言えるファイルです。ナビゲーションや一般的なタスクに役立つ短いコードが含まれています。
  • HubPage.xaml/.cs: アプリの最重要部分です。Hub コントロールが含まれています。
  • ItemPage.xaml/.cs: ハブ ページまたはセクション ページから移動できる、個別の項目が含まれています。
  • SectionPage.xaml/.cs: 特定のグループに属するすべての個別のデータ メンバーを表示します。
  • Package.appmanifest: アプリの設定が含まれています。

XAML ハブ プロジェクト テンプレートの HubPage.xaml ファイルを見ると、ページとハブのルート コンテナーとして機能する Grid コントロール内に、Hub コントロールが堂々と存在しているのがわかります。

DataModel フォルダーには、サンプル データを含んだ SampleData.json ファイルがあります。また、SampleDataSource.cs ファイルも DataModel フォルダーにあります。SampleDataSource.cs ファイルは、C# または Visual Basic の .NET 処理や XAML データ バインディングに使用できるクラスへと、JSON データを変換します。このサンプル データは、WinJS アプリの data.js ファイルと同じように独自のデータに置き換えることができます。

Common フォルダーには、さまざまなタスクを実行するファイルがいくつも含まれています。たとえば、ナビゲーションなど、ビュー モデルのデータを扱うための一般的なアプリ関連タスクを実行するファイルがあります。Common フォルダーには、プロセス ライフサイクル関連のタスクを実行する SuspensionManager.cs ファイルも含まれています。最後に、Strings フォルダーには、さまざまなロケールで公開するためのローカライズ済み文字列が含まれています。

Hub コントロール

HTML 用と XAML 用のどちらのプロジェクト テンプレートでも、Hub コントロールを使用します。HTML アプリの Hub コントロールのしくみは、他の WinJS コントロールとまったく同じです。次のコードに示すように、HTML 要素 (通常は <div>) の data-win-control 属性を使用して、要素を Hub コントロールとして定義します。

 

<div class="hub" data-win-control="WinJS.UI.Hub"></div>

つまり WinJS.UI.Hub オブジェクトが、Hub コントロールを背後で制御する要素です。Hub コントロールは HubSection コントロールのコンテナーとして機能し、HubSection コントロールでデータのセクションやグループを定義します。HubSection には、<div> や <img> などの任意の有効な HTML タグを含めることも、ListView コントロールなどの WinJS コントロールを含めることもできます。既定では、hub.html ファイルの Hub コントロールには 5 つのセクションが含まれています。1 つは hero という名前です。残りの 4 つの名前も class 属性 (section1、section2 など) で指定されています。HubSection では <div> タグと <img> タグが最も一般的な子要素ですが、任意の有効な HTML コントロールまたは WinJS コントロールを利用して、別のレイアウトでデータを表示することもできます。レイアウトの変更はアプリをカスタマイズする優れた方法ですが、msdn.microsoft.com/ja-jp/library/windows/apps/hh872191.aspx の Windows UX ガイドラインに従うことも忘れないでください。図 2 に、5 つのセクションがある Hub コントロールの作成に必要な、HTML のサンプル全体を示します (対応する CSS は後ほど示します)。図 2 のコードを調べると、セクション 3 のナビゲーションは機能しますが、他のセクションはナビゲーションが機能しないことがわかります。

図 2 Hub コントロールを作成する HTML

<div class="hub" data-win-control="WinJS.UI.Hub">
  <div class="hero" data-win-control="WinJS.UI.HubSection"></div>
  <div class="section1" data-win-control="WinJS.UI.HubSection"
     data-win-options="{ isHeaderStatic: true }"
     data-win-res="{ winControl: {'header': 'Section1'} }">
    <img src="/images/gray.png" width="420" height="280" />
    <div class="subtext win-type-x-large" data-win-res="
      { textContent: 'Section1Subtext' }"></div>
    <div class="win-type-medium"
       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
      <span data-win-res="{ textContent: 'Section1Description' }"></span>
    </div>
  </div>
  <div class="section2" data-win-control="WinJS.UI.HubSection" data-win-options="{
 isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section2'} }">
  <div class="item-title win-type-medium" data-win-res="{ textContent: 'Section2ItemTitle' }"></div>
    <div class="article-header win-type-x-large" data-win-res="{ textContent: 'Section2Subtext' }"></div>
    <div class="win-type-xx-small" data-win-res="{ textContent: 'Section2ItemSubTitle' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
      <span data-win-res="{ textContent: 'Section2Description' }"></span>
    </div>
  </div>
  <div class="section3" data-win-control="WinJS.UI.HubSection" data-win-res="{
 winControl: {'header': 'Section3'} } "data-win-options="{
    onheaderinvoked: select('.pagecontrol').winControl.section3HeaderNavigate }">
    <div class="itemTemplate" data-win-control="WinJS.Binding.Template">
      <img src="#" data-win-bind="src: backgroundImage; alt: title" />
      <div class="win-type-medium" data-win-bind="textContent: title"></div>
      <div class="win-type-small" data-win-bind="textContent: description"></div>
      </div>
      <div class="itemslist win-selectionstylefilled" data-win-control="WinJS.UI.ListView"
        data-win-options="{layout: {type: WinJS.UI.GridLayout},
        selectionMode: 'none', itemTemplate: select('.section3 .itemTemplate'),
        itemDataSource:select('.pagecontrol').winControl.section3DataSource,
         oniteminvoked: select('.pagecontrol').winControl.section3ItemNavigate }">
      </div>
    </div>
  <div class="section4" data-win-control="WinJS.UI.HubSection" data-win-options="{
   isHeaderStatic: true }" data-win-res="{ winControl: {'header': 'Section4'} }">
    <div class="top-image-row">
      <img src="/images/gray.png" />
    </div>
    <div class="sub-image-row">
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
      <img src="/images/gray.png" />
    </div>
    <div class="win-type-medium"       data-win-res="{ textContent: 'DescriptionText' }"></div>
    <div class="win-type-small">
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
      <span data-win-res="{ textContent: 'Section4Description' }"></span>
    </div>
  </div>
</div>

XAML の Hub コントロールでは、<Hub.Header> 要素と <HubSection> 要素を含む <Hub> 要素を使用します。これらの子要素のヘッダーとセクションには、Grid や他の XAML コントロール (StackPanel など) に加えて、テキスト ブロックが含まれています。図 3 に、Visual Studio テンプレートで使用される、Hub コントロールの作成に必要な XAML を示します。

図 3 Hub コントロール用の XAML

<Hub SectionHeaderClick="Hub_SectionHeaderClick">
  <Hub.Header>
    <!-- Back button and page title -->
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="80"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>
      <Button  x:Name="backButton" Style="{StaticResource NavigationBackButtonNormalStyle}"
        Margin="-1,-1,39,0"
        VerticalAlignment="Top"
        Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
        AutomationProperties.Name="Back"
        AutomationProperties.AutomationId="BackButton"
        AutomationProperties.ItemType="Navigation Button"/>
      <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}"
        Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
        VerticalAlignment="Top" IsHitTestVisible="false" TextWrapping="NoWrap" />
    </Grid>
  </Hub.Header>
  <HubSection Width="780" Margin="0,0,80,0">
    <HubSection.Background>
      <ImageBrush ImageSource="Assets/MediumGray.png" Stretch="UniformToFill" />
    </HubSection.Background>
  </HubSection>
  <HubSection Width="500" x:Uid="Section1Header" Header="Section 1">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png" Stretch="Fill" Width="420" Height="280"/>
          <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
            Grid.Row="1" Margin="0,10,0,0" TextWrapping="Wrap"
            x:Uid="Section1Subtitle" Text="Lorem ipsum dolor sit nonumy sed consectetuer ising elit, sed diam"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
            Grid.Row="2" Margin="0,10,0,0" x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
            x:Uid="Section1DescriptionText" Text="Lorem ipsum dolor sit amet... "/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection Width="520" x:Uid="Section2Header" Header="Section 2">
    <DataTemplate>
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Style="{StaticResource TitleTextBlockStyle}"
           Margin="0,0,0,10" x:Uid="ItemTitle" Text="Item Title" />
        <TextBlock Style="{StaticResource SubheaderTextBlockStyle}"
           Grid.Row="1" x:Uid="Section2UnderTitle" Text="Quisque in porta
           lorem dolor amet sed consectetuer ising elit, sed diam non
           my nibh uis mod wisi quip."/>
        <TextBlock Style="{StaticResource SubtitleTextBlockStyle}"
           Grid.Row="2" Margin="0,20,0,0" x:Uid="ItemSubTitle"
           Text="Item Sub Title"/>
        <TextBlock Style="{StaticResource BodyTextBlockStyle}" Grid.Row="3"
          x:Uid="LongText" Text="Lorem ipsum dolor sit amet..."/>
      </Grid>
    </DataTemplate>
  </HubSection>
  <HubSection IsHeaderInteractive="True"
     DataContext="{Binding Section3Items}" d:DataContext="{Binding Groups[3],
     Source={d:DesignData Source=/DataModel/SampleData.json,
     Type=data:SampleDataSource}}" x:Uid="Section3Header" Header="Section 3"
     Padding="40,40,40,32">
    <DataTemplate>
      <GridView
        x:Name="itemGridView"
        ItemsSource="{Binding Items}"
        Margin="-9,-14,0,0"
        AutomationProperties.AutomationId="ItemGridView"
        AutomationProperties.Name="Items In Group"
        ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="ItemView_ItemClick">
      </GridView>
    </DataTemplate>
  </HubSection>
  <HubSection x:Uid="Section4Header" Header="Section 4">
    <DataTemplate>
      <!-- width of 400 -->
      <StackPanel Orientation="Vertical">
        <Grid>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="130"/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition Height="270"/>
            <RowDefinition Height="95"/>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
          </Grid.RowDefinitions>
          <Image Source="Assets/MediumGray.png"
             Grid.ColumnSpan="5" Margin="0,0,0,10" Stretch="Fill" />
          <Image Source="Assets/MediumGray.png" Grid.Row="1" Stretch="Fill"/>
           <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="2" Stretch="Fill"/>
          <Image Source="Assets/MediumGray.png" Grid.Row="1"
              Grid.Column="4" Stretch="Fill"/>
          <TextBlock Style="{StaticResource TitleTextBlockStyle}"
             Grid.Row="2" Grid.ColumnSpan="5"  Margin="0,15,0,0"
            x:Uid="DescriptionHeader" Text="Description text:"/>
          <TextBlock Style="{StaticResource BodyTextBlockStyle}"
             Grid.Row="3" Grid.ColumnSpan="5" x:Uid="LongText"
             Text="Lorem ipsum dolor sit amet...."/>
        </Grid>
      </StackPanel>
    </DataTemplate>
  </HubSection>
</Hub>

ご覧のとおり、XAML 構文は HTML より少し冗長です。これは、レイアウトとスタイルも XAML ページでコーディングするためです (ただし、XAML スタイルをリソース ディクショナリに配置することもできます)。一方、HTML の場合はレイアウトとスタイル ルールを CSS でコーディングします (スタイル設定については後ほど詳しく説明します)。

データ バインディングと Hub コントロール

配列または (通常は最終的に配列にシリアル化される) JSON は、WinJS でも、その他多くの Web 言語やクライアント言語でも、データを扱う一般的な方法です。これはハブ プロジェクトでも同じです。\js\data.js のデータをカスタム データと置き換えて、使用を予定している任意の数のグループにこのカスタム データを分割しておくことができます。data.js ファイルには、サンプル データとして 2 つの配列が用意されています。1 つはグループ用の配列で、もう 1 つは特定のグループに結び付いた個別の項目用の配列です。他の WinJS プロジェクト テンプレートに精通している方は、ハブ プロジェクトのサンプル データが他のプロジェクトと同じことにお気付きでしょう。

\pages\hub\hub.js ファイルでは、Data 名前空間のメンバーを呼び出して、グループと項目のデータを取得します。

var section3Group = Data.resolveGroupReference("group4");
var section3Items = Data.getItemsFromGroup(section3Group);

section3Group と section3Items はグローバル オブジェクトです。図 2 、ListView コントロールのデータ バインディング構文を示しています。hub.js では、ready 関数の後に、Hub コントロールのプロパティである section3DataSource を設定します。

section3DataSource: section3Items.dataSource,

Hub コントロールでは、このコードを使用して ListView へのデータ バインディングを行います (図 2 にデータ バインディング先の ListView コードを示しています)。

C# を使用した XAML アプリでも、基本処理は同様です。HubPage.xaml.cs ファイルのコードでは、次のように、ObservableDictionary 型のビュー モデルを宣言すると同時に、対応するプロパティ (独自のデータを返せる部分) を宣言しています。

private ObservableDictionary defaultViewModel = new ObservableDictionary();
public ObservableDictionary DefaultViewModel
{
  get { return this.defaultViewModel; }
}

このファイルでは、後で GetGroupAsync メソッドを呼び出して、ページ レベルのビュー モデルを設定します。GetGroupAsync メソッドは、名前からわかるように非同期で実行されます。

var sampleDataGroup = await SampleDataSource.GetGroupAsync("Group-4");

この呼び出しでは Group-4 というデータを取得していますが、このデータを Section3Items というビュー モデルに割り当てることで、データをセクション 3 の項目に割り当てます。メインのセクションをセクション 0 と見なせば、セクション 3 の項目は Group-4 のデータと結び付くことになります。

this.DefaultViewModel["Section3Items"] = sampleDataGroup;

これで、分離コードに必要な処理は完了です。XAML では DataContext 属性を section3items にバインディングしていることに注意してください。他の属性はデータ バインディングに必要ではありませんが、"d" 名前空間で指定しているとおり、Visual Studio や Blend のデザイン ツールに役立ちます。

<HubSection IsHeaderInteractive="True" DataContext="{Binding Section3Items}" 
  d:DataContext="{Binding Groups[3], Source={d:DesignData
  Source=/DataModel/SampleData.json, Type=data:SampleDataSource}}"
  x:Uid="Section3Header" Header="Section 3" Padding="40,40,40,32">

ローカル サンプル データを扱っている場合も、データ アクセスには多くのオプションがあります。ほんの数例を挙げるだけでも、ファイル IO、SQLite、Web ストレージ、IndexedDB、REST サービス、Windows Azure などがあります。利用可能なデータ オプションについては、2013 年 3 月号のこのコラム「Windows ストア アプリにおけるデータ アクセスとストレージのオプション」(msdn.microsoft.com/magazine/jj991982、英語) を参照してください。

Hub コントロールにスタイルを設定する

JavaScript を使って構築した Windows ストア アプリには、Hub コントロールのスタイルを CSS で設定できます。\hub\hub.css ファイルには、Hub コントロールに関する既定の CSS がすべて含まれています。自由に独自のスタイルを追加して、要素のサイズやレイアウトを変更することができます。図 4 に、hub.css の CSS 全体を示します。.hubpage クラス セレクターで、header[role=banner] や section[role=main] などの HTML5 セマンティック role 属性を使用してハブの全般的なスタイルを指定していることに注目してください。図 4 の CSS で直後に示している ".hubpage .hub .hero" 子孫セレクターは、Hub コントロールのメイン (hero) セクションを作成します。hero は画面の表示可能領域のうち左側の約半分を占め、背景は薄い灰色です。これはもちろん、ユーザーが見落とさない場所に特別なコンテンツを配置する優れた方法です。hero セクションには大量のデータを表示できるので、ここにグラフィック データやマルチメディアを配置するとユーザーの注目を集めるのに効果的です。

図 4 HTML Hub コントロールの形とスタイルを設定する CSS

.hubpage header[role=banner] {
  position: relative;
  z-index: 2;
}
.hubpage section[role=main] {
  -ms-grid-row: 1;
  -ms-grid-row-span: 2;
  z-index: 1;
}
.hubpage .hub .win-hub-surface {
  height: 100%;
}
.hubpage .hub .hero {
  -ms-high-contrast-adjust: none;
  background-image: url(/images/gray.png);
  background-size: cover;
  margin-left: -80px;
  margin-right: 80px;
  padding: 0;
  width: 780px;
}
  .hubpage .hub .hero:-ms-lang(
    ar, dv, fa, he, ku-Arab, pa-Arab, prs, ps, sd-Arab,
     syr, ug, ur, qps-plocm) {
    margin-left: 80px;
    margin-right: -80px;
  }
  .hubpage .hub .hero .win-hub-section-header {
    display: none;
  }
  .hubpage .hub .section1 {
    width: 420px;
  }
  .hubpage .hub .section1 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section1 .subtext {
    margin-bottom: 7px;
    margin-top: 9px;
  }
.hubpage .hub .section2 {
  width: 440px;
}
  .hubpage .hub .section2 .win-hub-section-content {
    overflow-y: hidden;
  }
  .hubpage .hub .section2 .item-title {
      margin-top: 4px;
      margin-bottom: 10px;
  }
  .hubpage .hub .section2 .article-header {
    margin-bottom: 15px;
  }
.hubpage .hub .section3 {
}
  .hubpage .hub .section3 .itemslist {
    height: 100%;
    margin-left: -10px;
    margin-right: -10px;
    margin-top: -5px;
  }
  .hubpage .hub .section3 .win-container {
    margin-bottom: 36px;
    margin-left: 10px;
    margin-right: 10px;
  }
  .hubpage .hub .section3 .win-item {
      height: 229px;
      width: 310px;
  }
      .hubpage .hub .section3 .win-item img {
        height: 150px;
        margin-bottom: 10px;
        width: 310px;
      }
.hubpage .hub .section4 {
  width: 400px;
}
  .hubpage .hub .section4 .win-hub-section-content {
        overflow-y: hidden;
  }
  .hubpage .hub .section4 .top-image-row {
    height: 260px;
    margin-bottom: 10px;
    width: 400px;
  }
    .hubpage .hub .section4 .top-image-row img {
      height: 100%;
       width: 100%;
    }
.hubpage .hub .section4 .sub-image-row {
  margin-bottom: 20px;
  display: -ms-flexbox;
  -ms-flex-flow: row nowrap;
  -ms-flex-pack: justify;
}
  .hubpage .hub .section4 .sub-image-row img {
    height: 95px;
     width: 130px;
  }

ご覧のとおり、図 4 の CSS は、Hub コントロールの形とスタイルを設定し、大部分の設定は HubSection のレイアウトとサイズに関連しています。HubSection 内にある要素と WinJS コントロールには、独自のスタイルで上書きしない限り、ui-light.css または ui-dark.css のスタイルが適用されます。

HTML アプリのスタイル設定には CSS を使用しますが、XAML アプリのスタイル設定には XAML を使用します。つまり、XAML では属性をタグに適用することで、リソースと呼ばれるスタイル定義を適用します。このような属性はいくつもあります。たとえば、TextBlock のスタイルを設定するコードは Style 属性であり、SubheaderTextBlockStyle という組み込み (静的リソース ディクショナリ) スタイルを参照しています。

<TextBlock Style="{StaticResource SubheaderTextBlockStyle} />

ページのレイアウトも XAML で設定します。これは、Hub、Grid などの全要素に画面上の位置のインライン座標とサイズが含まれているためです。図 3 のあちこちには余白、位置、行、列といった要素の配置設定があり、どれも XAML 内にインラインで指定されています。HTML は本来 Web テクノロジなので、HTML の代わりに CSS を使用して帯域幅を節約することには現実的なメリットがあります。XAML の場合はすべてをクライアント側で処理するので、UI キャッシュはそれほど大きな問題にならず、スタイル設定をインラインで指定できます。XAML のメリットは、レスポンシブ デザインの実現に必要な作業がごくわずかな点です。2 つの <RowDefinition> 要素の高さを "Auto" と "*" に設定するだけで十分です。

 

<Grid.RowDefinitions>
  <RowDefinition Height="Auto"/>
  <RowDefinition Height="*"/>
</Grid.RowDefinitions>

これらの行はアプリのビュー状態の変化に自動的に反応するので、レイアウトが滑らかになると同時に、コードを追加する必要がなくなります。図 3 には、自動的に高さを調整する行定義の参考例をいくつか示しています。

利用できるサンプル

Hub コントロールを変更し、データ取得とデータ バインディングを実行して、スタイルを設定したら、準備完了です。タイル、検索、その他の Windows 統合機能など、最新の機能も必ずアプリに追加しましょう。ハブ プロジェクト テンプレートは、HTML であれ XAML であれ、アプリをすばやく構築して公開する簡単な手段です。Hub コントロールを利用したハブ ナビゲーション パターンを使用すると、最新の UI 原則に従った効果的でリッチな UX を作り上げることができます。以下のページからは、Windows アプリ開発の多くの側面を扱った Hub コントロール サンプルをダウンロードできます。

Rachel Appel は 20 年を超える IT 業界での経験を持つマイクロソフトの元社員で、コンサルティング、執筆活動、および指導を行っています。彼女は Visual Studio Live!、DevConnections、MIX など、業界トップ クラスのカンファレンスで講演しています。専門分野は、マイクロソフトの各種開発ツールやオープン Web を重視したテクノロジとビジネスを連携させるソリューションの開発です。彼女のことをもっと知りたい方は、彼女の Web サイト rachelappel.com (英語) をご覧ください。

この記事のレビューに協力してくれた技術スタッフの Frank La Vigne (マイクロソフト) に心より感謝いたします。