まず初めに、このプログラムで実装する機能の動作を、下記に解説しておきます。
画面に表示された、「平家物語」と「方丈記」のリンクをクリックすると、先に表示されていたページが背後に倒れ、前面からクリックされたページが起き上がるように表示されます。ページには物語の冒頭の文言が表示されています(図1)。
|
図1:前面から次のページが起き上がるように表示される(クリックで拡大) |
今回のサンプルは以下よりダウンロードできます。
→ 今回のサンプルファイル(2.34MB)
新規プロジェクトの作成
早速サンプルを作っていきましょう。本稿では開発言語にVisual Basicを用います。
VS 2010のメニューから[ファイル(F)/新規作成(N)/プロジェクト(P)]を選択します。次に、「Silverlight アプリケーション」を選択して、「名前(N)」に任意のプロジェクト名を指定します。ここでは「SL4_AnimePageNavigation」という名前を付けています。
ソリューションエクスプローラー内にリスト1のXMLファイルを取り込んでおきます。XMLファイルをLINQ to XMLで処理するため、「プロジェクト(P)/参照の追加(F)」から、System.Xml.Linqを追加しておいてください。
ダウンロードされたサンプル・ファイルにはXMLファイルは追加済みです。
リスト1 XMLファイル(Contents.xml)
01 | <?xml version="1.0" encoding="utf-8" ?> |
コントロールの配置
<UserControl>要素のWidthに800、Heightに600と指定します。Gridを2行に分け、1行目にStackPanelを配置し、その中に2個のHyperlinkButtonを配置します。StackPanelのOrientaionプロパティにHorizontalを指定し、HyperlinkButtonを水平に配置できるようにします。また、HorizontalAlignmentプロパティにCenterを指定します。
HyperlinkButtonのContentプロパティにはそれぞれ、「平家物語」、「方丈記」と指定します。「平家物語」のHyperlinkButtonのx:NameにはheikeBtn、「方丈記」にはhoujyoukiBtnと指定します。Gridの2行目にはFrameを配置します(図2)。
|
図2:StackPanel、2個のHyperlinkButton、Frameを配置した |
書き出されるXAMLはリスト2のようになります。
リスト2 書き出されたXAMLコード(Mainpage.xaml)
01 | <UserControl x:Class="SL4_AnimePageNavigation.MainPage" |
09 | <Grid x:Name="LayoutRoot" Background="White"> |
11 | <RowDefinition Height="47*" /> |
12 | <RowDefinition Height="553*" /> |
13 | </Grid.RowDefinitions> |
14 | <StackPanel Height="34" HorizontalAlignment="Left" Margin="34,13,0,0" Name="StackPanel1" VerticalAlignment="Top" Width="143" Orientation="Horizontal"> |
15 | <HyperlinkButton Content="平家物語" Height="25" Name="heikeBtn" Width="77" /> |
16 | <HyperlinkButton Content="方丈記" Height="25" Name="houjyoukiBtn" Width="60" /> |
18 | <sdk:Frame Grid.Row="1" Height="531" HorizontalAlignment="Left" Margin="14,10,0,0" Name="Frame1" VerticalAlignment="Top" Width="535" /> |
リスト2の中にTransitioningContentControlを配置します。このコントロールはSilverlight4 Toolkitに含まれています。下記URLよりSilverlight_4_Toolkit_April_2010.msiをダウンロードしてインストールしておいてください。
→ Silverlight 4 Toolkit - April 2010
このコントロールは、コンテンツの切り替え時にトランジション効果を伴って切り替わるコントロールです。使用するには、VS2010のメニューから「プロジェクト(P)/参照の追加(F)」と選択して、System.Windows.Controls.Layout.Toolkitを追加してください(図3)。
|
図3:「参照の追加(F)」からSystem.Windows.Controls.Layout.Toolkitを追加する(クリックで拡大) |
次に<UserControl>要素内に名前空間を追加します。xmlns:toolkit=”と入力すると、値の一覧が表示されますので、その中から、http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkitを選択します(図4)。「参照の追加(F)」からSystem.Windows.Controls.Layout.Toolkitを追加していなければ、この値は表示されませんので、注意してください。
これで、TransitioningContentControlを使用できる準備は整いました。
|
図4:toolkitという名前空間を追加する。値を選択している(クリックで拡大) |
toolkitという名前空間を追加したところで、リスト2をリスト3のように編集します。
リスト3 編集したXAMLコード(Mainpage.xaml)
01 | (1)<UserControl.Resource>プロパティ要素内にTransitionStyleというキーの<Style>要素を定義します。スタイルの対象となる型を指定するTargetTypeプロパティにsdk:Frameを指定します。ここで定義したスタイルは<sdk:Frame>に適用されます。 |
02 | (2)<Style>要素は1つ以上の<Setter>要素を持ちます。<Setter>要素のPropertyプロパティにTemplateを指定します。 |
03 | (3)<Setter.Value>プロパティ要素内に、<Setter>要素 で指定されたPropertyプロパティ(ここではTemplate)に適用する値を設定します。 |
04 | (4)<ControlTemplate>要素内に、コントロール テンプレートとして適用される要素を定義します。TargetTypeプロパティには、<ControlTemplate>要素の適用対象の型を指定します。ここでは、sdk:Frameを指定しています。 |
05 | (5)名前がTransitioningContentControl1という<toolkit:TransitioningContentControl>を配置します。ContentプロパティにTemplateBindingでContentをバインドします。TemplateBindingはControlTemplate内でのみ使用可能で、公開されているプロパティの値にリンクします。この記述がないと内容が表示されませんので、注意してください。 |
06 | (6)Frame1という名前の<sdk:Frame>のStyleプロパティに、Style="{StaticResource TransitioningStyle}"と記述して、<toolkit:TransitioningContentControl>要素を配置した定義済みの、TransitioningStyleという名前の<Style>要素を参照させます。 |
08 | <UserControl x:Class="SL4_AnimePageNavigation.MainPage" |
16 | <UserControl.Resources> ■(1) |
17 | <Style x:Key="TransitioningStyle" TargetType="sdk:Frame"> ■(1) |
18 | <Setter Property="Template"> ■(2) |
20 | <ControlTemplate TargetType="sdk:Frame"> ■(4) |
22 | <toolkit:TransitioningContentControl x:Name="TransitioningContentControl1" Content="{TemplateBinding Content}" /> ■(5) |
28 | </UserControl.Resources> |
30 | <Grid x:Name="LayoutRoot" Background="White"> |
32 | <RowDefinition Height="47*" /> |
33 | <RowDefinition Height="553*" /> |
34 | </Grid.RowDefinitions> |
35 | <StackPanel Height="34" HorizontalAlignment="Left" Margin="34,13,0,0" Name="StackPanel1" VerticalAlignment="Top" Width="143" Orientation="Horizontal"> |
36 | <HyperlinkButton Content="平家物語" Height="25" Name="heikeBtn" Width="77" /> |
37 | <HyperlinkButton Content="方丈記" Height="25" Name="houjyoukiBtn" Width="60" /> |
39 | <sdk:Frame Grid.Row="1" Height="531" HorizontalAlignment="Left" Margin="14,10,0,0" Name="Frame1" VerticalAlignment="Top" Width="535" Style="{StaticResource TransitioningStyle}"/> ■(6) |
Silverlightページの追加
VS2010メニューの「プロジェクト(P)/新しい項目の追加(W)」と選択し、「Silverlightページ」を選択します。「名前(N)」はheike.xamlとしています(図5)。同じ手順で、houjyouki.xamlという「Silverlightページ」も作成しておいてください。
|
図5:heike.xamlという「Silverlghtページ」を作成する(クリックで拡大) |
heike.xamlのデザイン画面上にTextBlockコントロールを2個配置します。タイトル用と内容を表示するTextBlockコントロールです(図6)。<navigation:Page>要素のTitleにそれぞれ、「平家物語」、「方丈記」と指定してください。タイトル用のTextBlockの文字サイズは20で太字、内容用の文字サイズは14と指定します。houjyouki.xamlも全く同じ配置とします。
|
図6:heike.xamlのデザイン画面上にTextBlockコントロールを2個配置した(クリックで拡大) |
クラスの作成
VS2010メニューの「プロジェクト(P)/新しい項目の追加(W)」と選択し、「クラス」を選択します。「名前(N)」はデフォルトのClass1.vbのままにしています(図7)。
|
図7:クラスを作成する(クリックで拡大) |
クラスのコードを記述するコード画面が表示されますので、リスト4のコードを記述します。
クラスのロジックコードを記述する
リスト4 (Class1.vb)
03 | XML文書をLINQ to XMLで処理するクラスの含まれる、System.Xml.Linq名前空間をインポートしておきます。 |
04 | Imports System.Xml.Linq |
06 | XML要素を表すXElementクラスのメンバ変数xmldocを宣言しておきます。 |
07 | Dim xmldoc As XElement |
09 | ■インスタンスを作成する場合に呼び出されるNewパブリックプロシージャ |
10 | XElement.LoadメソッドでXML文書ファイル(Contents.xml)を読み込みます。 |
12 | xmldoc = XElement.Load("Contents.xml") |
15 | ■XML文書内の”title”属性の値を返す関数 |
16 | Indexに該当する、<情報>要素の子要素<内容>の属性”title”の値を取得し戻り値とします。 |
17 | Function ReadTitle(ByVal Index As Integer) As String |
18 | Dim title = xmldoc.Descendants("情報")(Index).Element("内容").Attribute("title").Value |
23 | Indexに該当する、<情報>要素の子要素<内容>の値を取得し戻り値とします。 |
24 | Function ReadNaiyou(ByVal Index As Integer) As String |
25 | Dim naiyou = xmldoc.Descendants("情報")(Index).Element("内容").Value |
次にMainPage.xamlのHyperlinkButtonのTagプロパティにリスト5のように、先ほど作成しておいた、「Silverlightページ」を指定します。
リスト5 HyperlinkButtonのTagプロパティに「Silverlightページ」を指定した(MainPage.xaml)
1 | (1)HyperlinkButtonのTagプロパティにheilke.xamlとhoujyouki.xamlを指定する。 |
3 | <StackPanel Height="34" HorizontalAlignment="Left" Margin="34,13,0,0" Name="StackPanel1" VerticalAlignment="Top" Width="143" Orientation="Horizontal"> |
4 | <HyperlinkButton Content="平家物語" Height="25" Name="heikeBtn" Width="77" Tag="heike.xaml"/> ■(1) |
5 | <HyperlinkButton Content="方丈記" Height="25" Name="houjyoukiBtn" Width="60" Tag="houjyouki.xaml"/> ■(1) |
MainPage.xaml.vb内にリスト6のコードを記述します。
ロジックコードを記述する(MainPage.xaml.vb)
リスト6
03 | Partial Public Class MainPage |
11 | 2つのHyperlinkButtonがクリックされた時、NavigateToPageプロシージャを実行します。 |
12 | Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded |
13 | AddHandler heikeBtn.Click, AddressOf NavigateToPage |
14 | AddHandler houjyoukiBtn.Click, AddressOf NavigateToPage |
18 | Navigateメソッドで、HyperlinkButtonのTagプロパティに指定されたページにナビゲートします。 |
19 | Private Sub NavigateToPage(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) |
20 | Frame1.Navigate(New Uri("/" +DirectCast(sender, HyperlinkButton).Tag.ToString, UriKind.Relative)) |
次に「Silverlightページ」であるheike.xaml.vbにリスト5のコードを記述します。
ロジックコードを記述する
リスト5 (heike.xaml.vb)
1 | ■ユーザーがこのページに移動した時に実行されます |
2 | Class1の新しいインスタンス_myClassを宣言し、Class1.vbクラス内に記述した関数に、インデックスを指定して呼び出します。タイトルと内容が表示されます。 |
3 | Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs) |
4 | Dim _myClass As New Class1 |
5 | TextBlock1.Text = _myClass.ReadTitle(0) |
6 | TextBlock2.Text = _myClass.ReadNaiyou(0) |
同様にhoujyouki.xaml.vbにも同じコードを記述します。ただし引数となるインデックスには1を指定します。
次に該当するページがアニメーションを伴って表示される処理を、Expression Blend 4で実装します。
ソリューションエクスプローラー内の、MainPage.xamlを選択し、マウスの右クリックで表示されるメニューの、「Expression Blendを開く(X)」を選択し、Blend4を起動します。
Blend4でのアニメーションの作成
「オブジェクトとタイムライン(B)」内のFrame1を選択し、マウスの右クリックで表示されるメニューから、「テンプレートの編集(E)/現在のテンプレートの編集(U)」と選択します(図8)。
|
図8:Frame1を選択し、「テンプレートの編集(E)/現在のテンプレートの編集(U)」と選択する |
「オブジェクトとタイムライン(B)」内にTransitionContentControl1が表示されますので、これを選択してマウスの右クリックで表示されるメニューから、「テンプレートの編集(E)/コピーして編集(C)」と選択します(図9)。
|
図9:TransitionContentControl1を選択し、「テンプレートの編集(E)/コピーして編集(C)」と選択する(クリックで拡大) |
「Styleリソースの作成」画面が表示され、「名前(キー)」が自動的に付けられていますので、そのままで[OK]ボタンをクリックします。
「オブジェクトとタイムライン(B)」内に[Grid]が表示され、展開すると2つの要素が表示されます。最初のPreviousContentPresentationSiteを選択して、プロパティを見ると「種類」がContentPresenterになっているのがわかります。ContentPresenterオブジェクトは、ContentPresenter のコンテンツを表示するオブジェクトです。また、「状態」パネル内にはTransitionContentControlの持つ切り替え効果の一覧が表示されます。切り替え効果の秒数には0.5sと指定します(図10)。
|
図10:オブジェクトとタイムライン(B)」内に、PreviousContentPresentationSiteとCurrentContentPresentationSiteが表示される。これらはContentPresenterである。「状態」パネル内にはTransitionContentControlの持つ切り替え効果の一覧が表示されている(クリックで拡大) |
PreviousContentPresentationSiteとCurrentContentPresentationSiteのWidthとHeightをGridのサイズに合わせます。このサンプルではWidthが535、Heightが531になります。
「状態」パネル内のUpTransitionを選択します。すると、アートボード上の画面全体が赤の枠線で囲まれ、「●UpTransition状態記録オン」に変わります。この状態でタイムラインの記録が可能になります。タイムラインを表示させ、PreviousContentPresentationSiteを選択して、タイムラインを表示させます。既にPreviousContentPresentationSiteとCurrentContentPresentationSiteには、再生ヘッド上に楕円のマークが表示されていますが、楕円を選択してマウスの右クリックで表示される「削除」メニューから全て削除してください。
PreviousContentPresentationSiteを選択して、黄色い再生ヘッドを0秒に合わせます。プロパティの[変換]パネルにあるProjectionの「回転の中心」アイコンをクリックして、Xに0.5、Yに1と入力します(図11)。
|
図11:[変換]パネルにあるProjectionの「回転の中心」アイコンをクリックして、Xに0.5、Yに1と入力する |
次に再生ヘッドを0.2の位置に移動し、[変換]パネルにあるProjectionの「回転」アイコンをクリックしてXに-20と入力します。-20と入力しても-20.0021という半端な数値が入力されます(図12)。Opacityに67と指定します。次に再生ヘッドを0.6の位置に移動しXに-90と入力します。PreviousContentPresentaionSiteが図13のようになります。また、Opacityに0と指定します。
|
図12:[変換]パネルにあるProjectionの「回転」アイコンをクリックしてXに-20と入力する。-20と入力しても-20.0021という半端な数値が入力される |
|
図13:PreviousContentPresentaionSite が底面にくる |
次に、「タイムラインとオブジェクト(B)」内のCurrentContentPresentaionSiteを選択し、黄色の再生ヘッドが0の位置で何も設定しない状態で「キーフレームの記録」アイコンをクリックします(図14)。再生ヘッド上に楕円マークが表示されます。この時Opacityの値は0です。
次に、再生ヘッドを0.2の位置に移動し、[変換]パネルにあるProjectionの「回転」のXに90と入力し、「回転の中心」のXに0.5、Yに1と指定します。Opacityに33と指定します。CurrentContentPresentaionSiteが手前に倒れて表示されます (図15)。最後に再生ヘッドを0.6の位置に移動し「回転」のXの値に0を指定します。この時、Opacityの値は100です。
|
図14:再生ヘッドが0の位置で「キーフレームの記録」アイコンをクリックする |
|
図15:CurrentContentPresentaionSite が手前に倒れて表示される(クリックで拡大) |
「●UpTransition状態記録オン」の●をクリックして記録オフにします。
ここまでのタイムラインの記録をまとめると表1のようになります。
表1 UpTransition
オブジェクト名 | プロパティ | 再生ヘッド(秒) |
---|
0 | 0.2 | 0.6 |
---|
PreviousContentPresentaionSite | Projection(回転の中心) | X=0.5、Y=1 | X=0.5、Y=1 | X=0.5、Y=1 |
---|
Projection(回転) | 0 | X=-20 | X=-90 |
---|
Opacity | 100 | 67 | 0 |
---|
CurrentContentPresentaionSite | Projection(回転の中心) | [キーフレームの記録]をクリック | X=0.5、Y=1 | X=0.5、Y=1 |
---|
Projection(回転) | X=90 | X=0 |
---|
Opacity | 0 | 33 | 100 |
---|
ここで、一度Blend4上での操作を終了して、VS2010に戻ります。
書き出されたXAMLコードのリスト6の箇所を、リスト7のように修正します。
リスト6 元のXAMLコード(MainPage.xaml)
02 | <UserControl.Resources> |
04 | <Style x:Key="TransitioningContentControlStyle1" TargetType="toolkit:TransitioningContentControl"> |
05 | <Setter Property="IsTabStop" Value="True"/> |
06 | <Setter Property="HorizontalContentAlignment" Value="Left"/> |
07 | <Setter Property="VerticalContentAlignment" Value="Top"/> |
08 | <Setter Property="Transition" Value="DefaultTransition"/>■ここをリスト7のように修正 |
09 | <Setter Property="Template"> |
リスト7 修正したXAMLコード(MainPage.xaml)
01 | (1)Blend4でUpTransitionに対してタイムラインを設定したので、ここをUpTransitionに書き換えます。 |
03 | <UserControl.Resources> |
05 | <Style x:Key="TransitioningContentControlStyle1" TargetType="toolkit:TransitioningContentControl"> |
06 | <Setter Property="IsTabStop" Value="True"/> |
07 | <Setter Property="HorizontalContentAlignment" Value="Left"/> |
08 | <Setter Property="VerticalContentAlignment" Value="Top"/> |
09 | <Setter Property="Transition" Value="UpTransition"/>■(1) |
10 | <Setter Property="Template"> |
上記のようにコードを書き換えると、VS2010のデザイン画面上にエラーが表示され、デザイン画面が使用できなくなります(図16)。原因は不明ですが、実行には問題ありません。これ以後デザイン画面はBlend4上で確認する必要があります。
|
図16:VS2010のデザイン画面にエラーが表示されて使用不可となる(クリックで拡大) |
※筆者の環境でだけ生じるエラーかもしれません。
ここで一度VS2010メニューの「デバッグ(D)/デバッグ開始(S)」と選択して実行してみましょう。図17のように、「平家物語」や「方丈記」のリンクをクリックすると、最初に表示されていたページが背後に倒れ、次のページが起き上がって表示されます。
|
図17:最初に表示されていたページが背後に倒れ、次のページが起き上がって表示される(クリックで拡大) |
図1を見るとページの背景色が設定されています。ページの背景色を設定しましょう。
ページの背景色を設定する
ページの背景色はBlend4上で設定しますが、その前にXAMLコードに<Border>要素を追加しておきます。リスト8のコードにリスト9のように<Border>要素を追加してください。
リスト8 (MainPage.xaml)
03 | <ContentPresenter x:Name="PreviousContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Width="535" Height="531" Margin="-1,1,0,0"> |
04 | <ContentPresenter.Projection> |
05 | <PlaneProjection CenterOfRotationY="1"/> |
06 | </ContentPresenter.Projection> |
07 | <ContentPresenter.RenderTransform> |
09 | </ContentPresenter.RenderTransform> |
11 | <ContentPresenter x:Name="CurrentContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Width="535" Height="531" Margin="1,0,0,0"> |
12 | <ContentPresenter.Projection> |
13 | <PlaneProjection CenterOfRotationY="1"/> |
14 | </ContentPresenter.Projection> |
15 | <ContentPresenter.RenderTransform> |
17 | </ContentPresenter.RenderTransform> |
リスト9 <Border>要素を追加したコード(MainPage.xaml)
01 | (1)x:NameがPreviousContentPresentationSiteとCurrentContentPresentationSiteの<ContentPresenter>要素を<Border>要素で挟みます。 |
05 | <ContentPresenter x:Name="PreviousContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Width="535" Height="531" Margin="-1,1,0,0"> |
06 | <ContentPresenter.Projection> |
07 | <PlaneProjection CenterOfRotationY="1"/> |
08 | </ContentPresenter.Projection> |
09 | <ContentPresenter.RenderTransform> |
11 | </ContentPresenter.RenderTransform> |
15 | <ContentPresenter x:Name="CurrentContentPresentationSite" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Width="535" Height="531" Margin="1,0,0,0"> |
16 | <ContentPresenter.Projection> |
17 | <PlaneProjection CenterOfRotationY="1"/> |
18 | </ContentPresenter.Projection> |
19 | <ContentPresenter.RenderTransform> |
21 | </ContentPresenter.RenderTransform> |
MainPage.xamlを選択してExpression Blend4を起動します。
図8から図10の手順で(ただし、図9の場合は、既にテンプレートが作成されていますので、「現在のテンプレートの編集(U)」を選択します)、「オブジェクトとタイムライン(B)」内にPreviousContentPresentationSiteとCurrentContentPresentationSiteを表示させます。これら2つのオブジェクトが今回は[Border]の子として表示されます(図18)。PreviousContentPresentationSiteとCurrentContentPresentationSiteに黄色のびっくりマークの付けいた三角の警告マークが表示されますが、無視して構いません。
|
図18:PreviousContentPresentationSiteとCurrentContentPresentationSite が[Border]の子として表示される |
最初の[Border]を選択し、プロパティの[ブラシ]パネルにあるBackgroundに水色系統色を指定します。2番目の[Border]には緑系統色を指定します。
次に「状態(S)」パネル内のUpTranstionを選択し、最初の[Border]を選択します。タイムラインを表示し、表1を参考に、PreviousContentPresentationSiteと全く同じキーフレームを登録します。 プロパティの[変換]パネルにあるProjectionの値や、[外観]パネルにある Opacityの値も、PreviousContentPresentationSiteと全く同じにします。CurrentContentPresentationSiteの[Border]についても同様です。CurrentContentPresentationSiteと同じキーフレームを[Border]に設定してください。表1を参考にキーフレームを設定してください。図19のようになります。
|
図19:各[Border]にPreviousContentPresentationSiteとCurrentContentPresentationSite と同じキーフレームを設定した |
最後に、アートボードの上部に表示されているオブジェクトの一覧からFrame1を選択し、「オブジェクトとタイムライン(B)」内のLayoutRootを選択し、プロパティの[ブラシ]パネルにあるBackgroundに「グラデーションブラシ」をデフォルトのままで設定します。グレーのグラデーションがかかります。
Blend4のメニューの「プロジェクト(P)/プロジェクトの実行(R)」と選択して実行してみましょう(図20)。
|
図20:各[Border]に背景色を指定して実行した(クリックで拡大) |
Blend4を終了し、VS2010上からも実行して動作を確認しておきましょう。