コントロールの視覚効果とパノラマページの背景画像を変える

2011年7月11日(月)
PROJECT KySS

Panorama Pageの追加

VS2010メニューの「プロジェクト(P)/新しい項目の追加(W)」と選択して、Windows Phone Panorama Pageを追加します。「名前(N)」はデフォルトのPanoramaPage1のままにしています(図10)。

3

図10:Windows Phone Panorama Page を追加する(クリックで拡大)

書き出されるXAMLコードをリスト4のように編集します。

リスト4 書き出され編集されたXAMLコード(PanoramaPage1.xaml)

(1)まず、<controls:Panorama Title="my application">のTitleプロパティを削除します。
(2)<controls:Panorama>要素の子要素として、<controls:Panorama.Background>プロパティ要素を記述し、その中に<ImageBrush x:Name="ImageBrush1"/>と記述します。<ImageBrush>要素にはImageBrush1というx:Nameを付けておきます。この<ImageBrush>要素のImageSourceにMainPage.xamlから選択された画像が渡され表示されます。
(3)<controls:PanoramaItem>要素が2個記述されています。この要素はいくらでも増やすことができます。
(4)最初の<controls:PanoramaItem>要素のHeaderプロパティに「説明」と指定します。子要素として<Grid>要素を記述し、その中に<Border>要素を記述し、<Border> 要素の子要素として<TextBlock>を記述します。<Border>要素のBackgroundプロパティにはBeigeを指定し、Opacityには0.5を指定して半透明化しておきます。<TextBlock>要素のForegroundプロパティにはCrimsonを指定し、文字色を赤系統色にしています。またTextWrappingプロパティにはWrapを指定して文字の回り込みを有効にしています。
(5)2個目の<controls:PanoramaItem>要素のHeaderプロパティに「背景画像の変化」と指定します。子要素として<Grid>要素を記述し、その中に<TextBlock>を記述します。<TextBlock>要素のForegroundプロパティにはNavyを指定し、文字色を紺色にしています。またTextWrappingプロパティにはWrapを指定して文字の回り込みを有効にしています。
各<controls:PanoramaItem>ページへの遷移には、タッチによる横スライドで可能になります(タッチスクリーン使用時)。マウスではドラッグで横スライドが可能です。
  全て設定すると図11のようになります。
  <phone:PhoneApplicationPage
    x:Class="WP7_Image_Panorama.PanoramaPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait"  Orientation="Portrait"
    shell:SystemTray.IsVisible="False">

    <!--LayoutRoot contains the root grid where all other page content is placed-->
    <Grid x:Name="LayoutRoot">
      <controls:Panorama> ■(1)
        <controls:Panorama.Background> ■(2)
          <ImageBrush x:Name="ImageBrush1"/>
        </controls:Panorama.Background>
          <!--Panorama item one-->
        <controls:PanoramaItem Header="説明"> ■(3)、■(4)
          <Grid>
            <Border BorderBrush="Silver" BorderThickness="1" Height="268" HorizontalAlignment="Left" Margin="19,22,0,0" Name="Border1" VerticalAlignment="Top" Width="410" Background="Beige" Opacity="0.5">
              <TextBlock x:Name="TextBlock1" FontSize="20" TextWrapping="Wrap" Height="253" Foreground="Crimson" />
            </Border>
          </Grid>
        </controls:PanoramaItem>

        <!--Panorama item two-->
        <controls:PanoramaItem Header="背景画像の変化"> ■(3)、■(5)
          <Grid>
            <TextBlock x:Name="TextBlock2" FontSize="32" TextWrapping="Wrap" Foreground="Navy" />
          </Grid>
        </controls:PanoramaItem>
      </controls:Panorama>
  
  </Grid>
  <!--Panorama-based applications should not show an ApplicationBar-->
</phone:PhoneApplicationPage>

3

図11:Panorama Page にコントロールを配置しプロパティを設定した(クリックで拡大)

ソリューションエクスプローラー内のMainPage.xamlを展開し、表示されるMainPage.xaml.vbをダブルクリックしてリスト5のロジックコードを記述します。

ロジックコードを記述する

リスト5 ListBoxに画像一覧が表示される処理 (MainPage.xaml.vb)

Option Strict On
LINQ to XMLを利用するためSystem.Xml.Linq名前空間をインポートしています。
Imports System.Xml.Linq

ImageInfoクラス内に「画像名」という文字列型のプロパティを定義しています。
Public Class ImageInfo
  Property 画像名 As String
End Class

Partial Public Class MainPage
  Inherits PhoneApplicationPage
  ' Constructor

XElement型のxmldocをメンバ変数として宣言します。
  Dim xmldoc As XElement
  Public Sub New()
    InitializeComponent()
  End Sub

■ページが読み込まれた時の処理
XElement.LoadメソッドでXML文書ファイル(photo_etc.xml)を読み込みます。
新しいImageInfoクラス型のリストであるmyImageInfoオブジェクトを生成します。
<情報>要素のコレクションに対して、各要素を変数 result に格納しながら以下の処理を繰り返します。
ImageInfoクラスの「画像名」プロパティに、画像の置いてあるImageフォルダを連結した、<画像名>要素の値を指定し、AddメソッドでmyImageInfoオブジェクトに追加していきます。
ListBoxのItemsSourceにmyImageInfoオブジェクトを指定します。これで、ListBoxに画像の一覧が表示されます。

  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    xmldoc = XElement.Load("photo_etc.xml")
    Dim myImageInfo As New List(Of ImageInfo)
    For Each result In From c In xmldoc.Descendants("情報") Select c
      myImageInfo.Add(New ImageInfo With {.画像名 = "Image/" & result.Element("画像名").Value})
    Next
    ListBox1.ItemsSource = myImageInfo
  End Sub

■ListBoxコントロールより任意の画像を選択した時の処理
ListBoxの選択された項目のインデックスに該当する、<情報>要素の子要素<画像名>の値を、変数imageNameに格納します。
ListBoxの選択された項目のインデックスに該当する、<情報>要素の子要素<説明>の値を、変数naiyouに格納します。
NavigationService.NavigateメソッドでPanoramaPage1.xamlに遷移します。UriKind.Relativeとし相対URIで指定します。その際、URL の最後に「? キーワード = 遷移先に渡す文字列」という形で引数を付けて、遷移先のページに文字データを渡しています。ここではImageNameというキーワードにimageNameの文字データを指定しています。複数の引数を指定する場合は「&キーワード=遷移先に渡す文字列」と記述します。ここでは、Naiyouというキーワードにnaiyouを指定して遷移先に渡しています。
  Private Sub ListBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
    Dim imageName As String = xmldoc.Descendants("情報")(ListBox1.SelectedIndex).<画像名>.Value
    Dim naiyou As String = xmldoc.Descendants("情報")(ListBox1.SelectedIndex).<説明>.Value
    NavigationService.Navigate(New Uri("/PanoramaPage1.xaml?ImageName=" & imageName & "&Naiyou=" & naiyou, UriKind.Relative))
  End Sub
End Class

ソリューションエクスプローラー内のPanoramaPage1.xamlを展開し、表示されるPanoramaPage1.xaml.vbをダブルクリックしてリスト6のロジックコードを記述します。

リスト6 MainPageからの引数を受け取り、パノラマの背景画像を表示する処理(PanoramaPage1.xaml.vb)

Option Strict On

画像を表示させるのに必要なクラスの含まれる、System.Windows.Media.Imaging名前空間をインポートしておきます。
Imports System.Windows.Media.Imaging

Partial Public Class PanoramaPage1
  Inherits PhoneApplicationPage

  Public Sub New()
    InitializeComponent()
  End Sub

■画面の遷移で移動した時に最初に呼ばれるイベント
ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合ImageNameとNaiyou)を基に渡された文字列情報を取得します。
 リスト4の(2)で記述しておいたImageBrush1のImageSourceプロパティに、受け取った画像名(myParam(“ImageName”))の値を、画像の置かれているImageフォルダと連結して、相対URIで指定します。これで、パノラマの背景画像がMainPage.xamlで選択された画像に変わります。TextBlock1にはmyParam(“Naiyou”)の値を表示します。TextBlock2にはmyParam(“ImageName”)に格納されている画像名を表示します。
  Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    Dim myParam As IDictionary(Of String, String) = Me.NavigationContext.QueryString
    ImageBrush1.ImageSource = New BitmapImage(New Uri("Image/" & myParam("ImageName"), UriKind.Relative))
    TextBlock1.Text = myParam("Naiyou")
    TextBlock2.Text = "Panoramaの背景画像が、" & vbCrLf & "【" & myParam("ImageName") & "】に変わっています。"
    MyBase.OnNavigatedTo(e)
  End Sub

■エミュレーターのBack(s)ボタンのイベントを上書きする処理
エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
NavigationService.NavigateメソッドでMainPage.xamlに遷移します。
このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(s)をクリックした際エラーが発生しますので、注意してください。
Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください(図12)。
  Protected Overrides Sub OnBackKeyPress(e As System.ComponentModel.CancelEventArgs)
    e.Cancel = True
    NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative))
    MyBase.OnBackKeyPress(e)
  End Sub
End Class

3

図12:Protected Overrides Subと入力して、イベントの一覧が表示された(クリックで拡大)
  • 「コントロールの視覚効果とパノラマページの背景画像を変える」サンプルプログラム_1

  • 「コントロールの視覚効果とパノラマページの背景画像を変える」サンプルプログラム_2

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています