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

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)

01(1)まず、<controls:Panorama Title="my application">のTitleプロパティを削除します。
02(2)<controls:Panorama>要素の子要素として、<controls:Panorama.Background>プロパティ要素を記述し、その中に<ImageBrush x:Name="ImageBrush1"/>と記述します。<ImageBrush>要素にはImageBrush1というx:Nameを付けておきます。この<ImageBrush>要素のImageSourceにMainPage.xamlから選択された画像が渡され表示されます。
03(3)<controls:PanoramaItem>要素が2個記述されています。この要素はいくらでも増やすことができます。
04(4)最初の<controls:PanoramaItem>要素のHeaderプロパティに「説明」と指定します。子要素として<Grid>要素を記述し、その中に<Border>要素を記述し、<Border> 要素の子要素として<TextBlock>を記述します。<Border>要素のBackgroundプロパティにはBeigeを指定し、Opacityには0.5を指定して半透明化しておきます。<TextBlock>要素のForegroundプロパティにはCrimsonを指定し、文字色を赤系統色にしています。またTextWrappingプロパティにはWrapを指定して文字の回り込みを有効にしています。
05(5)2個目の<controls:PanoramaItem>要素のHeaderプロパティに「背景画像の変化」と指定します。子要素として<Grid>要素を記述し、その中に<TextBlock>を記述します。<TextBlock>要素のForegroundプロパティにはNavyを指定し、文字色を紺色にしています。またTextWrappingプロパティにはWrapを指定して文字の回り込みを有効にしています。
06各<controls:PanoramaItem>ページへの遷移には、タッチによる横スライドで可能になります(タッチスクリーン使用時)。マウスではドラッグで横スライドが可能です。
07  全て設定すると図11のようになります。
08  <phone:PhoneApplicationPage
09    x:Class="WP7_Image_Panorama.PanoramaPage1"
12    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
13    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
14    xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
17    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"
18    FontFamily="{StaticResource PhoneFontFamilyNormal}"
19    FontSize="{StaticResource PhoneFontSizeNormal}"
20    Foreground="{StaticResource PhoneForegroundBrush}"
21    SupportedOrientations="Portrait"  Orientation="Portrait"
22    shell:SystemTray.IsVisible="False">
23 
24    <!--LayoutRoot contains the root grid where all other page content is placed-->
25    <Grid x:Name="LayoutRoot">
26      <controls:Panorama> ■(1)
27        <controls:Panorama.Background> ■(2)
28          <ImageBrush x:Name="ImageBrush1"/>
29        </controls:Panorama.Background>
30          <!--Panorama item one-->
31        <controls:PanoramaItem Header="説明"> ■(3)、■(4)
32          <Grid>
33            <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">
34              <TextBlock x:Name="TextBlock1" FontSize="20" TextWrapping="Wrap" Height="253" Foreground="Crimson" />
35            </Border>
36          </Grid>
37        </controls:PanoramaItem>
38 
39        <!--Panorama item two-->
40        <controls:PanoramaItem Header="背景画像の変化"> ■(3)、■(5)
41          <Grid>
42            <TextBlock x:Name="TextBlock2" FontSize="32" TextWrapping="Wrap" Foreground="Navy" />
43          </Grid>
44        </controls:PanoramaItem>
45      </controls:Panorama>
46   
47  </Grid>
48  <!--Panorama-based applications should not show an ApplicationBar-->
49</phone:PhoneApplicationPage>

3

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

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

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

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

01Option Strict On
02LINQ to XMLを利用するためSystem.Xml.Linq名前空間をインポートしています。
03Imports System.Xml.Linq
04 
05ImageInfoクラス内に「画像名」という文字列型のプロパティを定義しています。
06Public Class ImageInfo
07  Property 画像名 As String
08End Class
09 
10Partial Public Class MainPage
11  Inherits PhoneApplicationPage
12  ' Constructor
13 
14XElement型のxmldocをメンバ変数として宣言します。
15  Dim xmldoc As XElement
16  Public Sub New()
17    InitializeComponent()
18  End Sub
19 
20■ページが読み込まれた時の処理
21XElement.LoadメソッドでXML文書ファイル(photo_etc.xml)を読み込みます。
22新しいImageInfoクラス型のリストであるmyImageInfoオブジェクトを生成します。
23<情報>要素のコレクションに対して、各要素を変数 result に格納しながら以下の処理を繰り返します。
24ImageInfoクラスの「画像名」プロパティに、画像の置いてあるImageフォルダを連結した、<画像名>要素の値を指定し、AddメソッドでmyImageInfoオブジェクトに追加していきます。
25ListBoxのItemsSourceにmyImageInfoオブジェクトを指定します。これで、ListBoxに画像の一覧が表示されます。
26 
27  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
28    xmldoc = XElement.Load("photo_etc.xml")
29    Dim myImageInfo As New List(Of ImageInfo)
30    For Each result In From c In xmldoc.Descendants("情報") Select c
31      myImageInfo.Add(New ImageInfo With {.画像名 = "Image/" & result.Element("画像名").Value})
32    Next
33    ListBox1.ItemsSource = myImageInfo
34  End Sub
35 
36■ListBoxコントロールより任意の画像を選択した時の処理
37ListBoxの選択された項目のインデックスに該当する、<情報>要素の子要素<画像名>の値を、変数imageNameに格納します。
38ListBoxの選択された項目のインデックスに該当する、<情報>要素の子要素<説明>の値を、変数naiyouに格納します。
39NavigationService.NavigateメソッドでPanoramaPage1.xamlに遷移します。UriKind.Relativeとし相対URIで指定します。その際、URL の最後に「? キーワード = 遷移先に渡す文字列」という形で引数を付けて、遷移先のページに文字データを渡しています。ここではImageNameというキーワードにimageNameの文字データを指定しています。複数の引数を指定する場合は「&キーワード=遷移先に渡す文字列」と記述します。ここでは、Naiyouというキーワードにnaiyouを指定して遷移先に渡しています。
40  Private Sub ListBox1_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ListBox1.SelectionChanged
41    Dim imageName As String = xmldoc.Descendants("情報")(ListBox1.SelectedIndex).<画像名>.Value
42    Dim naiyou As String = xmldoc.Descendants("情報")(ListBox1.SelectedIndex).<説明>.Value
43    NavigationService.Navigate(New Uri("/PanoramaPage1.xaml?ImageName=" & imageName & "&Naiyou=" & naiyou, UriKind.Relative))
44  End Sub
45End Class

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

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

01Option Strict On
02 
03画像を表示させるのに必要なクラスの含まれる、System.Windows.Media.Imaging名前空間をインポートしておきます。
04Imports System.Windows.Media.Imaging
05 
06Partial Public Class PanoramaPage1
07  Inherits PhoneApplicationPage
08 
09  Public Sub New()
10    InitializeComponent()
11  End Sub
12 
13■画面の遷移で移動した時に最初に呼ばれるイベント
14ここで、MainPage.xamlから渡された文字データを受け取ります。文字データはNavigationContextのQueryStringにDictionary として提供されます。送信時のキーワード(この場合ImageNameとNaiyou)を基に渡された文字列情報を取得します。
15 リスト4の(2)で記述しておいたImageBrush1のImageSourceプロパティに、受け取った画像名(myParam(“ImageName”))の値を、画像の置かれているImageフォルダと連結して、相対URIで指定します。これで、パノラマの背景画像がMainPage.xamlで選択された画像に変わります。TextBlock1にはmyParam(“Naiyou”)の値を表示します。TextBlock2にはmyParam(“ImageName”)に格納されている画像名を表示します。
16  Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
17    Dim myParam As IDictionary(Of String, String) = Me.NavigationContext.QueryString
18    ImageBrush1.ImageSource = New BitmapImage(New Uri("Image/" & myParam("ImageName"), UriKind.Relative))
19    TextBlock1.Text = myParam("Naiyou")
20    TextBlock2.Text = "Panoramaの背景画像が、" & vbCrLf & "【" & myParam("ImageName") & "】に変わっています。"
21    MyBase.OnNavigatedTo(e)
22  End Sub
23 
24■エミュレーターのBack(s)ボタンのイベントを上書きする処理
25エミュレーターの持っている本来のBack処理を、e.Cancel=Trueで無効とします。
26NavigationService.NavigateメソッドでMainPage.xamlに遷移します。
27このBackボタンのイベントを上書きする処理を記述していないと、エミュレーターのBack(s)をクリックした際エラーが発生しますので、注意してください。
28Protected Overrides Subと入力すると、インテリセンス機能が働き、イベントの一覧が表示されますので、その中から選択してください(図12)。
29  Protected Overrides Sub OnBackKeyPress(e As System.ComponentModel.CancelEventArgs)
30    e.Cancel = True
31    NavigationService.Navigate(New Uri("/MainPage.xaml", UriKind.Relative))
32    MyBase.OnBackKeyPress(e)
33  End Sub
34End 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メルマガ会員のサービス内容を見る

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