Windows 10のようにGridViewコントロールをスクロールさせるには?[ユニバーサルWindowsアプリ開発]WinRT/Metro TIPS

GridViewコントロールはWindows 8.1/10でデフォルトの挙動が異なる。本稿では、この挙動をWindows 10に合わせるための方法を解説する。

» 2015年04月22日 05時00分 公開
[山本康彦BluewaterSoft/Microsoft MVP for Windows Platform Development]
WinRT/Metro TIPS
業務アプリInsider/Insider.NET

powered by Insider.NET

「WinRT/Metro TIPS」のインデックス

連載目次

 Windows 10では、GridViewコントロール(Windows.UI.Xaml.Controls名前空間)に項目を並べる方向とスクロールする方向が変わる。Windows 8.1向けに開発したWindowsランタイムアプリでGridViewコントロールを使っている場合、Windows 10にインストールすると他のWindows 10アプリと操作性が違ってしまう。Windows 8.1向けのアプリでも、GridViewコントロールのスクロール方向をWindows 10と同じにできないだろうか? 本稿ではその方法を解説する。なお、本稿のサンプルは「Windows Store app samples:MetroTips #104」からダウンロードできる。

事前準備

 ユニバーサルプロジェクトを使ってユニバーサルWindowsアプリを開発するには、以下の開発環境が必要である。本稿では、無償のVisual Studio Community 2013 with Update 4を使っている。

  • SLAT対応のPC*1
  • 2014年4月のアップデート*2適用済みの64bit版Windows 8.1 Pro版以上*3
  • Visual Studio 2013 Update 2(またはそれ以降)*4を適用済みのVisual Studio 2013(以降、VS 2013)*5

*1 SLAT対応ハードウエアは、Windows Phone 8.1エミュレーターの実行に必要だ。ただし未対応でも、ソースコードのビルドと実機でのデバッグは可能だ。SLAT対応のチェック方法はMSDNブログの「Windows Phone SDK 8.0 ダウンロードポイント と Second Level Address Translation (SLAT) 対応PCかどうかを判定する方法」を参照。なお、SLAT対応ハードウエアであっても、VM上ではエミュレーターが動作しないことがあるのでご注意願いたい。

*2 事前には「Windows 8.1 Update 1」と呼ばれていたアップデート。スタート画面の右上に検索ボタンが(環境によっては電源ボタンも)表示されるようになるので、適用済みかどうかは簡単に見分けられる。ちなみに公式呼称は「the Windows RT 8.1, Windows 8.1, and Windows Server 2012 R2 update that is dated April, 2014」というようである。

*3 Windows Phone 8.1エミュレーターを使用しないのであれば、32bit版のWindows 8.1でもよい。

*4 マイクロソフトのダウンロードページから誰でも入手できる(このURLはUpdate 4のもの)。

*5 本稿に掲載したコードを試すだけなら、無償のExpressエディションやCommunityエディションで構わない。Visual Studio Express 2013 with Update 4 for Windows(製品版)はマイクロソフトのページから無償で入手できる。Expressエディションはターゲットプラットフォームごとに製品が分かれていて紛らわしいが、Windowsランタイムアプリの開発には「for Windows」を使う(「for Windows Desktop」はデスクトップで動作するアプリ用)。また、2014年11月12日(米国時間)に新しくリリースされたVisual Studio Community 2013 with Update 4(製品版)もマイクロソフトのページから無償で入手できる。Communityエディションは本稿執筆時点では英語版だけなので、同じ場所にあるVisual Studio 2013 Language Packの日本語版を追加インストールし、[オプション]ダイアログで言語を切り替える必要がある。


サンプルコードについて

 Visual Studio 2013 Update 2(Update 3/4も)では、残念なことにVB用のユニバーサルプロジェクトのテンプレートは含まれていない*6。そのため、本稿で紹介するVBのコードはユニバーサルプロジェクトではなく、PCL(ポータブルクラスライブラリ)を使ったプロジェクトのものである。

*6 VB用のユニバーサルプロジェクトは、2015年の夏にリリースされるといわれているVisual Studio 2015(開発コード「Visual Studio 14」)からの提供となるようだ。プレビュー版で、すでに共有プロジェクトは利用可能になっている。「特集:次期Visual Studioの全貌を探る:Visual Basic 14の新機能ベスト10〜もう「VBだから」とは言わせない!」参照。


Windows 10のUI変化

 Windows 8.x向けのWindowsランタイムアプリでは、アプリの主となるスクロール方向は横方向だった。これがWindows 10では縦方向に変更されたのである(次の画像)。Windows Phoneでは以前から縦方向であったので、そちらに合わせたと見ることもできる。

Windows 10での項目の並び方向とスクロール方向
Windows 10での項目の並び方向とスクロール方向
Windows 10での項目の並び方向とスクロール方向 Windows 10での項目の並び方向とスクロール方向
最初の2枚は、PC向けのWindows 10(Technical Previewビルド10041)の「ストア(ベータ)」アプリである。最後は、Windows 10 for phones(Technical Previewビルド10051)の「エクスプローラー」アプリだ(フォルダー名の並び順に注目)。
項目の配置は、まず左から右へ、それから下へという並びになっている。画面に収まらないときには上下方向にスクロールする(右にスクロールバーが出る)。Windows 8.xのWindowsランタイムアプリとは縦横の方向が入れ替わっているのだ(Windows 10用のGridViewコントロールもこのように変更される)。

 これはユーザーエクスペリエンス(UX)としては非常に重要な変化であるから、Windows 8.1向けのアプリに取り入れるかどうかは、難しい問題である。Windows 10でチャームがなくなることへの対応アプリバーが出しにくくなることへの対応は、画面にUIを追加するだけであった。それに対して、スクロール方向の変更というのは、単にGridViewコントロールの方向を変えるだけでは済まず、おそらくはUI設計の根本的な見直しが必要になるだろう。従って、既存のWindows 8.1向けのアプリはそのままにしておいて、Windows 10用に新しいバージョンを開発する方がよいと思われる。運よくUI設計の大幅変更にならなかった場合は、以降の解説を参考にしてWindows 10対応を考えてほしい。

元になるアプリを作る

 まず、GridViewコントロールを使った簡単なアプリを用意しよう。1から20までの数字を表示するものとする。表示するデータは、次のコードだ。

using System.Collections.Generic;
using System.Linq;

namespace MetroTips104CS
{
  public class SampleData
  {
    public IList<string> Numbers { get; private set; }

    public SampleData()
    {
      var list = new List<string>();
      list.AddRange(
          Enumerable.Range(1,20).Select(n => n.ToString())
        );
      this.Numbers = list;
    }
  }
}

Public Class SampleData
  Private _numbers As List(Of String) = New List(Of String)()
  Public Property Numbers As IList(Of String)
    Get
      Return _numbers
    End Get
    Private Set(value As IList(Of String))
      _numbers = value
    End Set
  End Property

  Public Sub New()
    _numbers.AddRange(
      Enumerable.Range(1, 20).Select(Function(n) n.ToString())
    )
  End Sub
End Class

表示するデータを提供するクラスの例(上:C#/下:VB)
Numberプロパティで、1から20までの数字を提供する。画面に表示された数字を見れば、項目の並び順が一目瞭然になるというわけだ。表示後にプロパティを変更することは考慮に入れていないため、ObservableCollectionクラスを使っていない。
このコードは、「SampleData.cs/.vb」というファイル名で共有プロジェクトに置く(VBではPCLプロジェクト)。

 次に、ユーザーコントロールを共有プロジェクト(VBではPCLプロジェクト)に作り、ファイル名を「NumbersGridNormal.xaml」とする。そのコンテンツとして、次のコードのようなGridViewコントロールを記述する。

<GridView Grid.Row="1" Width="300" ItemsSource="{Binding Numbers}">
  <GridView.Resources>
    <local:SampleData x:Key="SampleData" />
  </GridView.Resources>
  <GridView.DataContext>
    <StaticResource ResourceKey="SampleData"/>
  </GridView.DataContext>
  <GridView.ItemTemplate>
    <DataTemplate>
      <Grid Width="80" Height="80" Background="Blue">
        <TextBlock Text="{Binding}" FontSize="45" Foreground="White" 
                    FontFamily="Segoe WP Black"
                    HorizontalAlignment="Center" VerticalAlignment="Center" />
      </Grid>
    </DataTemplate>
  </GridView.ItemTemplate>
</GridView>

通常のGridViewコントロールのコード例(XAML)
データソースの定義とスタイル定義もまとめて記述しているため少々煩雑になっているが、ご容赦願いたい。ItemTemplateプロパティで項目ごとの表示を変更しているが、項目の並び順やスクロール方向は既定のままである。
このコードは、「NumbersGridNormal.xaml」というファイル名で共有プロジェクト(VBではPCLプロジェクト)に作成したユーザーコントロールのコンテンツとして記述する。

 このユーザーコントロールをメイン画面に貼り付けて実行すると、次の画像のようになる。

元になるアプリを実行している様子(Windows 8.1)
元になるアプリを実行している様子(Windows Phone 8.1 元になるアプリを実行している様子(上:Windows 8.1/下:Windows Phone 8.1)
上:Windows 8.1では、GridViewコントロールの項目はまず上から下、それから右へと配置される。スクロール方向は左右である(下端にスクロールバーが見えている)。
下:Windows Phone 8.1では、GridViewコントロールの項目はまず左から右、それから下へと配置される。スクロール方向は上下だ。これはWindows 10と同じである。

GridViewコントロールを縦スクロールに変えるには?

 GridViewコントロールのスクロール方向と、ItemsPanelTemplateコントロール(Windows.UI.Xaml.Controls名前空間)の並び方向を変えればよい。

 具体的には、GridViewコントロールのXAMLコードを、次のコードのように変更する。元のコードと実行結果を区別するために、ここでは項目の背景色も変えている。

<GridView Grid.Row="1" Width="300" ItemsSource="{Binding Numbers}">
  <GridView.Resources>
    ……省略(前のコードと同じ)……
      <Grid Width="80" Height="80" Background="DarkRed">
    ……省略(前のコードと同じ)……
  </GridView.ItemTemplate>

  <!-- ItemsPanelTemplateの方向を横並びにする -->
  <GridView.ItemsPanel>
    <ItemsPanelTemplate>
      <VariableSizedWrapGrid Orientation="Horizontal" />
    </ItemsPanelTemplate>
  </GridView.ItemsPanel>

  <!-- スタイル定義で、スクロール方向を縦にする -->
  <GridView.Style>
    <Style TargetType="GridView">
      <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
      <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
      <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
      <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
    </Style>
  </GridView.Style>
</GridView>

スクロール方向を変更したGridViewコントロールのコード例(XAML)
省略した部分は、前のコードと同じである。「<GridView.ItemsPanel>」要素と「<GridView.Style>」要素を追加した。 スタイル定義はプロパティ要素構文で記述したが、属性として書いても構わない。
このコードは共有プロジェクト(VBではPCLプロジェクト)に置いたユーザーコントロールのものであり、Windows 8.1とWindows Phone 8.1の両方のプロジェクトで利用していることを思い出してほしい。Windows 8.1でスクロール方向を変更できるかに加えて、Windows Phone 8.1には悪影響がないかにも注意しなければならない。 なお、別途公開のサンプルでは、このコードは「NumbersGridVertical.xaml」というファイル名で、元のコードとは別のファイルにしてある。

 これで実行してみると、次の画像のようになる。Windows 8.1でも縦スクロールになっている。

GridViewコントロールのスクロール方向を変えたアプリを実行している様子(Windows 8.1)
GridViewコントロールのスクロール方向を変えたアプリを実行している様子(Windows Phone 8.1) GridViewコントロールのスクロール方向を変えたアプリを実行している様子(上:Windows 8.1/下:Windows Phone 8.1)
項目の背景が赤色のものが改修したコードである。
上:Windows 8.1でも、GridViewコントロールの項目を左から右、それから下へと配置できた。スクロール方向も上下に変わっている(右端にスクロールバーが見えている)。
下:Windows Phone 8.1は元からWindows 10と同じスクロール方向だが、上のコードのようにしても悪影響は見られない。

まとめ

 Windows 10では、Windows 8.1と比べて項目の並び順とスクロール方向の縦横が入れ替わる(Windows Phone 8.1と同じになる)。これはUXの大きな変更であり、既存のWindows 8.1向けアプリに採用するのは難しいものがある。ただし、そのようにGridViewコントロールを対応させることは、XAMLコードだけで簡単にできる。

「WinRT/Metro TIPS」のインデックス

WinRT/Metro TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。