まず初めに、このプログラムで実装する機能の動作を、下記に解説しておきます。
画面が表示されると、カードが折りたたまれ、加算された数値が表示されます。背面のカードに加算された数値が表示されており、折りたたまれると加算された数値が前面に表示されます(図1)。数値は60まで加算され、60に達する、とまた1から加算を開始します。
![3](https://i-blog.csdnimg.cn/blog_migrate/35f840685999f3a230bfb070dc1fcc58.png) |
図1:折りたたまれるように数値が加算されて表示される |
今回のサンプルは以下よりダウンロードできます。
→ 今回のサンプルファイル(125KB)
新規プロジェクトの作成
早速サンプルを作っていきましょう。本稿では開発言語にVisual Basicを用います。
VS 2010のメニューから[ファイル(F)/新規作成(N)/プロジェクト(P)]を選択します。次に、「Silverlight アプリケーション」を選択して、「名前(N)」に任意のプロジェクト名を指定します。ここでは「SL4_ParaParaTimer」という名前を付けています。
Silverlightユーザーコントロール(TimerBaseSilverlightControl.xaml)の作成
VS2010のメニューから「プロジェクト(P)/新しい項目の追加(W)」と選択し、「Silverlightユーザーコントロール」を作成します。「名前(N)」には「TimerBaseSilverlightControl.xaml」と指定し、[追加(A)]ボタンをクリックします(図2)。
![3](https://i-blog.csdnimg.cn/blog_migrate/d8e97f05768cf4d3b05cc55b538bf569.png) |
図2:Silverlightユーザーコントロールを作成する(クリックで拡大) |
TimerBaseSilverlightControl.xamlの<UserControl>要素のHeightに350と指定します。WidthはAutoのままで構いません。ツールボックスからGridコントロールを配置します。プロパティの[レイアウト]パネル内のWidthに250、Heightに300と指定します。Gridコントロールに半分の分割線を引きます。Gridコントロールの縦の枠をクリックすると分割線を引くことができます(図3)。
![3](https://i-blog.csdnimg.cn/blog_migrate/bb25ca53a36cdf0b9d182beaea8460b9.png) |
図3:Gridコントロールを縦に2分割する |
次に、ソリューションエクスプローラー内の、TimerBaseSilverlightControl.xamlを選択し、マウスの右クリックで表示されるメニューの、「Expression Blendを開く(X)」を選択し、Blend4を起動します。
Blend4でのBorder、TextBlockの配置
「アセット(T)」パネルの「コントロール」からBorderを選択し、アートボードのGridの上の部分にBorderを配置します。プロパティの「名前」には、Border1と指定します。[外観]パネルにあるBorderThicknessに2を指定して枠線を太くし、CornerRadiusに8を指定して四隅を丸めます。[レイアウト]パネルにあるWidthに235、Heightに136と指定します(図4)。
![3](https://i-blog.csdnimg.cn/blog_migrate/25a0f3febcb5794320ed8827b65e99a0.png) |
図4:Gridコントロールを上部分にBorderコントロールを配置する(クリックで拡大) |
次に、Borderコントロールの背景色を設定します。プロパティの[ブラシ]パネルにあるBackgroundが選択された状態で、「グラデーションブラシ」をクリックします。色の「エディター」の中から適当な色を選択してください。このサンプルでは茶系統色を選択しています。下部よりも上部を少し明るくします。カラーストップを左右逆に入れ替えることで、上下の明るさを逆にすることができます。BorderBrushには青系統色を選択し、周囲を青系統色で囲っています(図5)。
![3](https://i-blog.csdnimg.cn/blog_migrate/08ac40f8256cd3fc4abee844db1314f0.png) |
図5:Borderコントロールの背景色と周囲の色を設定している(クリックで拡大) |
Borderコントロールの子要素としてTextBlockコントロールを配置します。「名前」はTextBlock1とします。[共通プロパティ]パネルにあるTextには01と指定し、[ブラシ]パネルにあるForegroundにGoldを指定して、文字色をGoldとします。[テキスト]パネルにある文字サイズには90と指定します。[レイアウト]パネルにあるVerticalAlignmentにはTopを指定します。Textプロパティに指定した01の文字の上半分だけが表示されるよう配置します。図6のようにTextBlockのMarginが「↓」以外、全て37になるように配置してください。
![3](https://i-blog.csdnimg.cn/blog_migrate/5f877786612bdfed6962229c916c1674.png) |
図6:Marginが全て37になるようTextBlockを配置する |
次に、今配置したGridの上の部分のBorderコントロールに、もう一つBorderコントロールを配置します。Border1を選択して、コピー&ペーストしてください。TextBlockも一緒にペーストされます。ペーストしたBorderの「名前」にBorder2、TextBlockの「名前」にTextBlock2と指定します。TextBlock2のTextプロパティには00と指定してください(図7)。
![3](https://i-blog.csdnimg.cn/blog_migrate/63acef355a442fba9f36c377e3fee275.png) |
図7:Gridの上の部分のBorderコントロールに、もう一つBorderコントロールを配置する |
次に、Border2を選択してコピーし、Gridの下の部分にペーストします。
Borderの「名前」はBorder3とします。一緒にペーストされたTextBlockは削除します。Border3の中に子要素となるようGridコントロールを配置します。TextBlock2を選択してコピーし、Gridコントロールの中に子要素となるようペーストします。TextBlockの「名前」はTextBlock3とします。Border2をコピーしたため、Borderの背景色のグラデーションが、上方が明るく、下方が暗くなっています。これを上方が暗く、下方を明るくします。色の「エディター」のカラーストップを左右逆にすることで、上下の明るさを逆にすることができます。Boder2とBorder3の境目が少しあく程度に配置します。TextBlock2とTextBlock3で00が完成されるように配置します。Border3の子要素としてGridコントロールを配置することを忘れないようにしてください(図8)。
![3](https://i-blog.csdnimg.cn/blog_migrate/d87fdd27606b3f05fe5a3ea38094d563.png) |
図8:Grid(Grid1) の下の部分にBorder(Border3) を配置し、その子要素として[Grid]を配置する。また[Grid]の子要素としてTextBlock(TextBlock3)を配置する(クリックで拡大) |
Border3の中に、もう1つTextBlockを配置します。「名前」はTextBlock4とします。TextBlock3を選択してコピーし、Border3の子要素[Grid]の中にペーストしてください。TextBlock3とTextBlock4は[Grid]の子要素となります。TextBlock4のTextプロパティは空にしておいてください。「オブジェクトとタイムライン(B)」で階層構造を見ると図9のようになっています。Border3の中に[Grid]を配置していなければ、TextBlockを2つ(TextBlock3とTextBlock4)配置することはできませんので、注意してください。
![3](https://i-blog.csdnimg.cn/blog_migrate/155a41798e931c31cd97da3fdf14b586.png) |
図9:配置したオブジェクトの階層構造 |
以上のコントロールの配置をまとめると下記のようになります。
■Grid(Grid1)の上の位置に配置するコントロール
-
(1):Border(Border1)
(2):TextBlock(TextBlock1、Border1の子として配置)
(3):Border(Border2)
(4):TextBlock(TextBlock2、Border2の子として配置)
■Grid(Grid1)の下の位置に配置するコントロール
-
(1):Border(Border3)
(2):Grid(Border3の子として配置)
(3):TextBlock(TextBlock3、Gridの子として配置)
(4):TextBlock(TextBlock4、Gridの子として配置)
※各コントロールのプロパティの設定については、前述の解説を参照してください。
Storyboardの作成
「新規作成」アイコンをクリックしてストーリーボードを作成します(図10)。
![3](https://i-blog.csdnimg.cn/blog_migrate/faa7da0ac959472c645cbbdfffb99c38.png) |
図10:ストーリーボードの「新規作成」アイコンをクリックする |
「Storyboardリソースの作成」ダイアログボックスが開きますので、「名前(キー)」はデフォルトのStoryboard1のままで[OK]ボタンをクリックします。アートボードが赤い枠線で囲まれ、「●Storyboard1タイムライン記録オン」と表示されます。この状態からストーリーボードを作成していきます。
「オブジェクトとタイムライン(B)」内のBorder2を選択します。
黄色の再生ヘッドが「0」の位置で、プロパティの[変換]パネルにある、RenderTransformの「中心点」のXに0.5、Yに1と指定します(図11)。
![3](https://i-blog.csdnimg.cn/blog_migrate/73f153f8f813cf7b29c818bdec401ac2.png) |
図11:Border2のRenderTransformの「中心点」を設定する |
次に、TextBlock3を選択し、黄色の再生ヘッドが「0」の位置で、プロパティの[外観]パネルにある、VisibilityにCollapsedを指定します。TextBlock4を選択し、プロパティの[外観]パネルにあるVisibilityに一度Collapsedを指定し、再度Visibleを選択します。こうすることで、タイムラインにVisibilityが追加されます。
次に再生ヘッドを0.4の位置に移動し、TextBlock3を選択して、Visibilityの値をVisibleに指定します。同じくTextBlock4を選択し、今度はVisibilityにCollapsedを指定します。
再生ヘッドを0.8の位置に移動します。Border2を選択します。プロパティの[変換]パネルにある、RenderTransformの「拡大縮小」アイコンをクリックし、Yに-1と指定します(図12)。
![3](https://i-blog.csdnimg.cn/blog_migrate/015743b14bbe2067f31932a46f418fdc.png) |
図12:Border2のRenderTransformの「拡大縮小」のYの値に-1を設定する(クリックで拡大) |
以上のタイムラインの動きと各コントロールのプロパティをまとめると、表1のようになります。
表1:Storyboard1
オブジェクト名 | プロパティ名 | 再生ヘッド(秒) |
---|
0 | 0.4 | 0.8 |
---|
Border2 | RenderTransform | [中心点]X=0.5、Y=1 | - | [拡大縮小]X=1、 Y=-1 |
TextBlock3 | Visibility | Collapsed | Visible | - |
TextBlock4 | Visibility | Visible | Collapsed | - |
最終的にストーリーボードを開いた状態では、アートボード上に図13のように表示されるようにしてください。
![3](https://i-blog.csdnimg.cn/blog_migrate/126642915a45827678ccfcccc7f869ff.png) |
図13:最終的に表示されるコントロール |
TextBlockの位置がずれていると、表示される数値もずれて表示されます。TextBlockの位置は最終的にプログラムを動作させたのち微調整してください。Blend4の操作を終わりVS2010に戻ります。
MainPage.xaml内にTimerBaseSilverlightControlを取り込む
まず、<UserControl>要素のHeightに350と指定します。次にlocalという名前空間を、MainPage.xaml内の<UserControl>要素内で定義します。xmlns:local=””と入力すると、名前空間の値の一覧が表示されますので、現在作成しているプロジェクト名を選択します(図14)。
![3](https://i-blog.csdnimg.cn/blog_migrate/5ba0ceadfa6030148f65754dd284f6c5.png) |
図14:localという名前空間を定義する(クリックで拡大) |
次に、<Grid>要素内に、<local:と入力します。するとTimerBaseSilverlightControlが表示されますので、これを選択します(図15)。x:NameにmyNumberと指定します。MainPageのデザイン画面にコントロールが表示されます(図16)。x:Nameの指定を忘れないように注意してください。
![3](https://i-blog.csdnimg.cn/blog_migrate/a00d10272afd819ce2ec40e8e45a724b.png) |
図15:<Grid>要素内にTimerBaseSilverlightControl を取り込む |
![3](https://i-blog.csdnimg.cn/blog_migrate/6e4519e1527c7d32b4b51635ac50d827.png) |
図16:MaiPage内にコントロールが表示される |
ソリューションエクスプローラー内のMainPage.xamlを展開して表示される、MainPage.xaml.vbをダブルクリックしてリスト1のコードを記述します。
ロジックコードを記述する
リスト1 (MainPage.xaml.vb)
03 | タイマーに関するクラスの含まれる、System.Windows.Theading名前空間を読み込みます。 |
04 | Imports System.Windows.Threading |
05 | Partial Public Class MainPage |
11 | 加算される変数noをメンバ変数として宣言します。 |
15 | 新しいDispatcherTimerのインスタンスであるmyTimerオブジェクトを生成します。DispatcherTimerクラスは指定した時間の間隔で処理されるタイマーを表すクラスです。 |
16 | タイマー間隔が経過すると発生するTickイベント時に、myTimer_Tickプロシージャを指定します。 |
17 | Intervalプロパティでは、タイマーの間隔を指定します。ここでは1秒間隔でmyTimer_Tickプロシージャが実行されます。Startメソッドでタイマーを実行します。 |
18 | Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded |
19 | Dim myTimer As New DispatcherTimer |
20 | AddHandler myTimer.Tick, AddressOf Me.myTimer_Tick |
21 | myTimer.Interval = TimeSpan.FromSeconds(1) |
26 | Math.Min関数で、変数noの値が60より小さい場合は、変数noの値を1ずつ加算します。変数noの値が60になった時は0で初期化します。 |
27 | 各TextBlockのTextプロパティに加算されるnoの値と、さらに1が加算された値を指定します。 |
28 | カードがめくられた時は、表示されている値より、さらに1が加算された値が表示されるようになります。背面に配置されたTextBlockには、前面に配置されたTextBlockのTextの値より+1された値が表示されます。 |
29 | コントロールは最後に配置されているコントロールの方が前面に配置されます。 |
30 | Gridの上方に配置されていたTextBlockコントロールは、TextBlock1がTextBlock2の背面、TextBlock2がTextBlock1の前面に配置されます。 |
31 | また、Gridの下方に配置されていたTextBlockコントロールは、TextBlock3がTextBlock4の背面、TextBlock4がTextBlock3の前面に配置されます。 |
32 | よって背面に配置されているTextBlock1とTextBlock3にはTextBlock2とTextBlock4の値より+1された値が表示されるようにします。 |
33 | 00、01、02…、の表示にするため、ToStringに”00”の書式を指定しています。 |
34 | myNumberは、local:TimerBaseSilverlightControlに付けた名前です。 |
35 | BeginメソッドでStoryboard1を開始します。 |
36 | Private Sub myTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) |
37 | no = Math.Min(no + 1, 60) |
38 | If no = 60 Then no = 0 |
39 | myNumber.TextBlock1.Text = (no + 1).ToString("00") |
40 | myNumber.TextBlock2.Text = no .ToString("00") |
41 | myNumber.TextBlock3.Text = (no + 1).ToString("00") |
42 | myNumber.TextBlock4.Text = no.ToString("00") |
43 | myNumber.Storyboard1.Begin() |