連載
» 2015年09月02日 05時00分 UPDATE

WinRT/Metro TIPS:ハンバーガーメニューで画面を遷移させるには?[Windows 10 UWPアプリ開発] (1/2)

SplitViewコントロールとFrameコントロールを利用して、UWP内でハンバーガーメニューから画面遷移を行う方法を解説する。

[山本康彦,BluewaterSoft/Microsoft MVP for Windows Platform Development]
WinRT/Metro TIPS
業務アプリInsider/Insider.NET

powered by Insider.NET

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

連載目次

 Windows 10のユニバーサルWindowsプラットフォーム用のアプリ(以降、UWPアプリ)に特徴的なUIといえば、「ハンバーガーメニュー」(=ハンバーガーボタンによって開閉するメニュー)を使った画面遷移が挙げられる(次の画像)。これはどのようにして実装すればよいのだろうか? 複数の画面それぞれにハンバーガーメニューを実装するのだろうか? あるいは、ハンバーガーメニューの部分をユーザーコントロールとして作成し、それぞれの画面に貼り付けて使うのだろうか? 実は、Windows 10で新しく追加されたSplitViewコントロール(Windows.UI.Xaml.Controls名前空間)を使えば、ハンバーガーメニューの中で画面遷移を行えるのである。ASP.NET(Webフォーム)のマスターページとコンテンツページをご存じならば、それと同じような仕掛けだと言えばイメージは分かっていただけるだろう。

 本稿では、SplitViewコントロールを使い、ハンバーガーメニューで画面遷移を実装する例を説明する。ハンバーガーボタンの実装と、ハンバーガーボタンでSplitViewコントロールを開閉する方法については、「WinRT/Metro TIPS:ハンバーガーボタンを実装するには?[Windows 10 UWPアプリ開発]」をご覧いただきたい。なお、本稿のサンプルは「Windows Store app samples:MetroTips #112」からダウンロードできる。

ハンバーガーボタン(左上の赤色のボタン)をタップ/クリックする
ハンバーガーボタン(左上の赤色のボタン)をタップ/クリックする
ハンバーガーメニューが開くので、その[カテゴリ]/[Interests]項目(2番目の項目)をタップ/クリックする
ハンバーガーメニューが開くので、その[カテゴリ]/[Interests]項目(2番目の項目)をタップ/クリックする
「カテゴリ」/「Interests」画面に遷移した
「カテゴリ」/「Interests」画面に遷移した

ハンバーガーメニューによる画面遷移の例
これはWindows 10に標準の「ニュース」アプリである。それぞれの画像の左側は、デスクトップ用のもの。右側は、Windows 10モバイルエミュレーターで動かしているモバイル用のものである。
上: ハンバーガーメニューが閉じている状態。デスクトップ用では、ハンバーガーメニューを完全に隠さず、アイコンが見えるようにしている。モバイル用では、ハンバーガーメニューを完全に隠している。ここでハンバーガーボタン(左上の赤色のボタン)をタップ/クリックすると、ハンバーガーメニューが開く。
中: ハンバーガーメニューが開いている状態。このアプリでは、ハンバーガーメニューに表示されている項目の中で、現在表示している画面(この画像では[マイニュース]/[My News])に該当する項目の背景色を変えている(暗赤色)。ここで、例えば[カテゴリ]/[Interests]項目をタップ/クリックすると、ハンバーガーメニューは閉じられ、その画面に遷移する。
下: 画面遷移した状態。デスクトップ用では、縮小されたハンバーガーメニューの中で、遷移した画面に該当するアイコンの背景色が変わっている(モバイル用も同様なのだが、ハンバーガーメニューが完全に隠されているため、この画像では分からない)。


事前準備

 デスクトップ用とモバイル(=Windows 10を搭載したスマートフォン)用のUWPアプリを開発するには、以下の開発環境が必要である。本稿では、無償のVisual Studio Community 2015を使っている。

  • SLAT対応のPC*1
  • 64bit版*2 Windows 10 Pro*3
  • Visual Studio 2015(以降、VS 2015)*4
  • Windows SDK for Windows 10*5

 本稿では、「WinRT/Metro TIPS:ハンバーガーボタンを実装するには?[Windows 10 UWPアプリ開発]」を前提とする。ハンバーガーボタンのタップ/クリックでハンバーガーメニューを開閉する実装については、そちらをご覧いただきたい。

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

*2 Windows 10モバイルエミュレーターを使用しないのであれば、32bit版でもよい。

*3 開発に使うWindows 10は「開発者モード」を有効にしておくこと(「設定アプリ」の[更新とセキュリティ]−[開発者向け]で、[開発者モード]ラジオボタンを選択)。そうしないと、VS 2015のXAMLエディターがエラーになる。また、本稿の内容が適用できるのは、Windowsのライフサイクル管理の上では「Windows 10, released in July 2015」と呼ばれるリリース、またはそれ以降。WinVerコマンドで表示されるバージョンは「10.0 (ビルド 10240)」。UWPアプリ開発におけるデバイスファミリーのバージョン指定としては「10.0.0.0」(Package.appxmanifestファイルのTargetDeviceFamily)である。なお、モバイルエミュレーターを使用しないのであれば、Home版でもよい。

*4 本稿に掲載したコードを試すだけなら、無償のExpressエディションやCommunityエディションで構わない。Visual Studio Express 2015 for Windows 10(製品版)はマイクロソフトのページから無償で入手できる(ページの左側で[Visual Studio 2015]−[Express 2015 for Windows 10]と選ぶ)。Expressエディションはターゲットプラットフォームごとに製品が分かれていて紛らわしいが、UWPアプリの開発には「for Windows 10」を使う(「for Desktop」はWPF/Windowsフォーム/Win32 APIのアプリ開発用)。また、Visual Studio Community 2015(製品版)もマイクロソフトのページから無償で入手できる。なお、英語版がインストールされた場合には、Microsoft Visual Studio 2015 Language Packの日本語版を追加インストールし、[オプション]ダイアログで言語を切り替える

*5 使用しているVS 2015に含まれていない場合は、Windows SDK for Windows 10のページからダウンロードできる。本稿の内容が適用できるのは、作成したプロジェクトのプロパティに表示されるターゲットバージョンが「10.0; ビルド 10240」またはそれ以降。


これから実装するUIの構造

 最初に、ハンバーガーメニュー(SplitViewコントロール)と遷移する画面との関係を説明しておこう。

 本稿で実装するUIは、次の画像のようなものだ。

本稿で実装するUI(デスクトップ) 本稿で実装するUI(デスクトップ)
左側のハンバーガーメニューで[ページ【1】]/[ページ【2】]/[ページ【3】]を選ぶと、右側がそれぞれの画面に遷移する。
なお、ハンバーガーメニューの下端にある[About]は、タップ/クリックするとフライアウトを表示する。これについては本稿では解説しないので、別途公開のサンプルコードをご覧いただきたい。

 このUIの構造は、その概略を示すと次の図のようになっている。

本稿で実装するUIの構造(概略) 本稿で実装するUIの構造(概略)
先の画像と見比べていただきたい。「MainPage.xaml」の中にSplitViewコントロールがあって、そのPaneプロパティにハンバーガーメニューが実装されている。ContentプロパティにはFrameコントロール(Windows.UI.Xaml.Controls名前空間)を入れておき、そのFrameコントロールのNavigateメソッドを使って各ページ(「Page1.xaml」/「Page2.xaml」/「Page3.xaml」)を表示する。先の画像で「ページ【1】」と表示されている赤色の部分は「Page1.xaml」である。

 重要な点は、SplitViewコントロールのContentプロパティにFrameコントロール(Windows.UI.Xaml.Controls名前空間)を配置でき、そのFrameコントロールの中で通常のページをナビゲートできることである。

コンテンツに表示するページを作成する

 先に、上の図の「Page1.xaml」/「Page2.xaml」/「Page3.xaml」を作成しておこう(次のコード)。テキストブロックの他に、今回は[戻る]ボタンも実装しておく(ただし、これには問題がある。後述する)。

<Page
    ……省略……
    mc:Ignorable="d">
  <Grid RequestedTheme="Light" Background="#fff0f0">
    <!-- [戻る]ボタン -->
    <Button x:Name="BackButton" Click="BackButton_Click"
            Width="48" VerticalAlignment="Top" Background="Transparent">
      <Button.Content>
        <SymbolIcon Symbol="Back" />
      </Button.Content>
    </Button>
    <!-- テキストブロック -->
    <TextBlock FontFamily="Yu Gothic" FontSize="40"
               HorizontalAlignment="Center" VerticalAlignment="Center">
      ページ【1】
    </TextBlock>
  </Grid>
</Page>

コンテンツに表示するページの例(XAML)
これは「Page1.xaml」である。残りの「Page2.xaml」/「Page3.xaml」も同様に、ただし区別が付くように実装しておく。
今回はここに[戻る]ボタンも配置しているが、あまりよろしくない(後述)。より良い方法は、回をあらためて説明したい。

public sealed partial class Page1 : Page
{
  public Page1()
  {
    this.InitializeComponent();
  }

  protected override void OnNavigatedTo(NavigationEventArgs e)
  {
    base.OnNavigatedTo(e);

    BackButton.Visibility
      = Frame.CanGoBack ? Visibility.Visible : Visibility.Collapsed;
  }

  private void BackButton_Click(object sender, RoutedEventArgs e)
  {
    Frame.GoBack();
  }
}

Public NotInheritable Class Page1
  Inherits Page

  Protected Overrides Sub OnNavigatedTo(e As NavigationEventArgs)
    MyBase.OnNavigatedTo(e)

    BackButton.Visibility _
        = If(Frame.CanGoBack, Visibility.Visible, Visibility.Collapsed)
  End Sub

  Private Sub BackButton_Click(sender As Object, e As RoutedEventArgs)
    Frame.GoBack()
  End Sub
End Class

コンテンツに表示するページの例(コードビハインド、上:C#/下:VB)
これは「Page1.xaml」のコードビハインドである。[戻る]ボタンのハンドリングだけを行っている。残りの「Page2.xaml」/「Page3.xaml」も同様に実装しておく。
このC#のコードは、冒頭のusing句と名前空間宣言を省略している。

画面遷移用の項目をハンバーガーメニューに実装するには?

 ハンバーガーメニューに表示する項目の実装は、さまざまな方法が考えられる。画面遷移を伴わない機能、例えばフライアウトを出すといった用途では、通常のボタンでよいだろう。しかし、画面遷移をさせる場合は項目の選択状態を維持する必要がある。そうしないと、現在どの画面を表示しているのか(=どの項目を選択しているのか)が分からなくなってしまうからだ。すると、画面遷移を伴う機能を実装するときには、トグルボタンが使えそうである。ただし、もう一つ課題がある。同じ項目を2回タップ/クリックしても選択状態が解除されてはいけないのだ(同じ画面が表示されているのであるから)。トグルボタンを使う場合には、その対処が必要になる。

 ここでは、ラジオボタンを利用してみよう。選択状態は維持してくれるし、選択された状態の項目をさらにタップ/クリックしてもイベントは発生しない。画面遷移用の項目にはぴったりだ。外観には問題があるが、それは後からスタイルを変更しよう。

 すると、「MainPage.xaml」のSplitViewコントロールの部分は、次のコードのようになる。

<SplitView x:Name="Splitter" DisplayMode="CompactOverlay"
            CompactPaneLength="48" OpenPaneLength="320"
            ……省略……
            PaneBackground="DarkSeaGreen">

  <!-- Paneプロパティにはメニューを入れる -->
  <SplitView.Pane>
    <Grid RequestedTheme="Dark">
      <Grid.RowDefinitions>
        ……省略……
      </Grid.RowDefinitions>

      <!-- 上部のナビゲーションボタン -->
      <StackPanel Margin="0,32,0,0">
        <RadioButton x:Name="RadioButton1"
                      Checked="RadioButton1_Checked"
                      GroupName="Navi" 
                      >ページ【1】</RadioButton>
        <RadioButton x:Name="RadioButton2"
                      Checked="RadioButton2_Checked"
                      GroupName="Navi"
                    >ページ【2】</RadioButton>
        <RadioButton x:Name="RadioButton3"
                      Checked="RadioButton3_Checked"
                      GroupName="Navi"
                    >ページ【3】</RadioButton>
      </StackPanel>

      <!-- 下端の[About]ボタン -->
      ……省略……
    </Grid>
  </SplitView.Pane>

  <!-- ContentプロパティにはFrameコントロールを入れる -->
  <SplitView.Content>
    <Frame x:Name="MainContentFrame" />
  </SplitView.Content>
</SplitView>

「MainPage.xaml」のSplitViewコントロールの実装例(XAML)
画面遷移のために必要な部分のみを示す。 ハンバーガーボタンの実装と、ハンバーガーボタンでSplitViewコントロールを開閉する方法については、「WinRT/Metro TIPS:ハンバーガーボタンを実装するには?[Windows 10 UWPアプリ開発]」をご覧いただきたい。
下端の[About]ボタンについては、別途公開のサンプルコードをご覧いただきたい。 なお、冒頭の画像で紹介した「ニュース」アプリは、モバイルデバイスではハンバーガーメニューを完全に隠している。本稿では解説しないが、そうするにはAdaptiveTriggerクラス(Windows.UI.Xaml名前空間)を使ってSplitViewコントロールのDisplayModeプロパティを「Inline」または「Overlay」に切り替える。

 そして、画面遷移の項目がタップ/クリックされたときのイベントハンドラーは、次のコードのようになる。実にシンプルである。

public sealed partial class MainPage : Page
{
  public MainPage()
  {
    this.InitializeComponent();
  }

  protected override async void OnNavigatedTo(NavigationEventArgs e)
  {
    ……省略……

    // アプリ開始時には、ページ【1】を表示する
    RadioButton1.IsChecked = true;
  }

  // ハンバーガーメニューで[ページ【1】]が新たに選択された
  private void RadioButton1_Checked(object sender, RoutedEventArgs e)
  {
    MainContentFrame.Navigate(typeof(Page1));
    Splitter.IsPaneOpen = false;
  }

  // ハンバーガーメニューで[ページ【2】]が新たに選択された
  private void RadioButton2_Checked(object sender, RoutedEventArgs e)
  {
    MainContentFrame.Navigate(typeof(Page2));
    Splitter.IsPaneOpen = false;
  }

  // ハンバーガーメニューで[ページ【3】]が新たに選択された
  private void RadioButton3_Checked(object sender, RoutedEventArgs e)
  {
    MainContentFrame.Navigate(typeof(Page3));
    Splitter.IsPaneOpen = false;
  }
}

Public NotInheritable Class MainPage
    Inherits Page

  Protected Overrides Async Sub OnNavigatedTo(e As NavigationEventArgs)
    ……省略……

    ' アプリ開始時には、ページ【1】を表示する
    RadioButton1.IsChecked = True
  End Sub

  ' ハンバーガーメニューで[ページ【1】]が新たに選択された
  Private Sub RadioButton1_Checked(sender As Object, e As RoutedEventArgs)
    MainContentFrame.Navigate(GetType(Page1))
    Splitter.IsPaneOpen = False
  End Sub

  ' ハンバーガーメニューで[ページ【2】]が新たに選択された
  Private Sub RadioButton2_Checked(sender As Object, e As RoutedEventArgs)
    MainContentFrame.Navigate(GetType(Page2))
    Splitter.IsPaneOpen = False
  End Sub

  ' ハンバーガーメニューで[ページ【3】]が新たに選択された
  Private Sub RadioButton3_Checked(sender As Object, e As RoutedEventArgs)
    MainContentFrame.Navigate(GetType(Page3))
    Splitter.IsPaneOpen = False
  End Sub
End Class

MainPage.xaml」のコードビハインド(上:C#/下:VB)
ラジオボタンが選択されたとき、Frameコントロール(=「MainContentFrame」変数)のNavigateメソッドを使ってそれぞれの画面にナビゲートするだけである。ただし、ハンバーガーメニューは開いたままなので、SplitViewコントロール(=「Splitter」変数)のIsPaneOpenプロパティをFalseにすることでハンバーガーメニューを閉じる。
なお、このC#のコードは、冒頭のusing句と名前空間宣言を省略している。

       1|2 次のページへ

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

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

メールマガジン登録

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