仮想 通貨 リップル の 相場k8 カジノ文字列をコントロールにバインドするには?[Win 8/WP 8]仮想通貨カジノパチンコビット コイン の システム
この 付近 の パチンコ 店k8 カジノ
sim スロット 付き pcpowered by Insider.NET
連載目次
Windowsストア・アプリでデータを表示するにはデータ・バインドを使うのがよいといわれる。しかしドキュメントやサンプル・コードを読んでみても、何だか難しそうなうえに、とても範囲が広そうだ。どこから手を付けたらよいのだろうか?
そこで本稿では、最もシンプルな形のデータ・バインドを解説する。なお、掲載しているコードはWindowsストア・アプリのものだが、記述するコードはWindows Phone 8でも全く同じである。本稿のサンプルは「Windows Store app samples:MetroTips #31(Windows 8版)」と「Windows Store app samples:MetroTips #31(WP 8版)」からダウンロードできる。
●事前準備
Windows 8(以降、Win 8)向けのWindowsストア・アプリを開発するには、Win 8とVisual Studio 2012(以降、VS 2012)が必要である。これらを準備するには、第1回のTIPSを参考にしてほしい。本稿では64bit版Win 8 ProとVS 2012 Express for Windows 8を使用している。
Windows Phone 8向けのアプリを開発するには、SLAT対応CPUを搭載したPC上の64bit版Win 8 Pro以上とWindows Phone SDK 8.0(無償)が必要となる。
●データ・バインドはWindowsストア・アプリ開発の肝
Windowsストア・アプリでは、データ・アクセスは非同期に行うのが一般的だし、画面とは別にバックグラウンド・タスクでデータ・アクセスを行うパターンもよくある。同期アクセスが主体だった従来のデスクトップ・アプリの感覚で「メソッドを呼び出してデータを取得し、そのデータを使って画面を更新する」という明示的なやり方は、Windowsストア・アプリらしくないのだ。
時間の経過や何らかの処理によって動的に変化するデータを自動的に画面に反映させるには、データ・バインドが最適だ。データ・バインドの理解は、Windowsストア・アプリ開発には必須だといえるだろう。その第一歩として、時間の経過とともに変化する文字列をTextBlockコントロールにバインドするというごくシンプルなケースから始めよう。
●「デジタル時計」クラス
次の画像のような簡単なデジタル時計アプリを作ってみよう。ただし、画面とロジックの分離を考えて、時刻を提供するクラスを画面から独立させて作るものとする。
完成したデジタル時計アプリの画面(Win 8/WP 8)
時分秒の文字列を適度な精度で提供する簡易的な「デジタル時計」クラスは、次のコードのClockクラスのように実装できる。秒が変わるのを一定間隔(約10ミリ秒間隔)で監視し、変化したところでイベントを発生させるのだ。なお、INotifyPropertyChangedインターフェイス(System.ComponentModel名前空間)を継承し、発生させるイベントとしてPropertyChangedEventHandlerデリゲート(System.ComponentModel名前空間)を使っているのは、データ・バインドにも使えるようにするためだ。データ・バインドしないのならば、独自のイベント定義でも構わない。
public class Clock : INotifyPropertyChanged{ // 現在時刻を表す文字列のプロパティ "HH:mm:ss" public string NowTime { get; private set; } // NowTimeプロパティが変化したときに発生させるイベントの定義 // なお、このプロパティはINotifyPropertyChangedインターフェイスの実装である public event PropertyChangedEventHandler PropertyChanged; public Clock() { Run(); // 時刻監視の無限ループを動かす } private async void Run() { DateTimeOffset lastTime; while (true) { await Task.Delay(10); // おおよそ10ミリ秒ごとにシステム時計をチェックする var nowTime = DateTimeOffset.Now; if (lastTime.Second != nowTime.Second) { // 秒が変わったら、プロパティに時刻をセットし、イベントを発火させる this.NowTime = nowTime.ToString("HH:mm:ss"); if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("NowTime")); lastTime = nowTime; } } }}
Public Class Clock Implements INotifyPropertyChanged ' 現在時刻を表す文字列のプロパティ "HH:mm:ss" Private _nowTime As String Public Property NowTime As String Get Return _nowTime End Get Private Set(value As String) _nowTime = value End Set End Property ' NowTimeプロパティが変化したときに発生させるイベントの定義 Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) _ Implements INotifyPropertyChanged.PropertyChanged Public Sub New() Run() ' 時刻監視の無限ループを動かす End Sub Private Async Sub Run() Dim lastTime As DateTimeOffset While (True) Await Task.Delay(10) ' おおよそ10ミリ秒ごとにシステム時計をチェックする Dim nowTime = DateTimeOffset.Now If (lastTime.Second <> nowTime.Second) Then ' 秒が変わったら、プロパティに時刻をセットし、イベントを発火させる Me.NowTime = nowTime.ToString("HH:mm:ss") RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NowTime")) lastTime = nowTime End If End While End SubEnd Class
「デジタル時計」クラスのコード(上:C#、下:VB)デジタル時計のアプリは、このクラスのインスタンスでPropertyChangedイベントが発生したときに、NowTimeプロパティの値を使って画面を更新する。
●[実装その1]イベントをそのまま使う
データ・バインドを利用せず、イベントを使って実装してみよう。画面クラスのコンストラクタでイベント・ハンドラを設定し、イベント・ハンドラではClockクラスのNowTimeプロパティを参照して画面を描き変えるのだ。
画面としてMainPage.xamlファイルを作成しよう。そこに、時刻表示に使うテキスト・ブロックを次のコードのように記述する。
<TextBlock x:Name="textClock1" Text="00:00:00" FontSize="120" Foreground="LimeGreen" />
時刻表示のためのテキスト・ブロック(XAML)Textプロパティに値が設定してあるのは、XAMLエディタ上でデザインを確認するため。FontSizeプロパティとForegroundプロパティは適当でよい。
そうしたら、この画面のコードビハインド(=MainPage.xaml.csファイルまたはMainPage.xaml.vbファイル)に、Clockクラスのインスタンスとそのイベント・ハンドラを追加する(次のコードの太字部分)。
// 「デジタル時計」クラスのインスタンスprivate Clock _clock1 = new Clock();public MainPage(){ this.InitializeComponent(); // 【1】「デジタル時計」クラスのイベント・ハンドラを設定する _clock1.PropertyChanged += clock1_PropertyChanged;}// 【1】「デジタル時計」クラスのプロパティが変化したときに呼び出されるハンドラvoid clock1_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e){ textClock1.Text = _clock1.NowTime;}
' 「デジタル時計」クラスのインスタンスPrivate _clock1 As Clock = New Clock()Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 ' 【1】「デジタル時計」クラスのイベント・ハンドラを設定する AddHandler _clock1.PropertyChanged, AddressOf clock1_PropertyChangedEnd Sub' 【1】「デジタル時計」クラスのプロパティが変化したときに呼び出されるハンドラPrivate Sub clock1_PropertyChanged(sender As Object, e As PropertyChangedEventArgs) textClock1.Text = _clock1.NowTimeEnd Sub
「デジタル時計」のイベントをイベント・ハンドラで処理するコード(上:C#、下:VB)
これでビルドして動作することを確かめてほしい。
このようにイベント・ハンドラを使っても目的を達することはできる。しかし、この方法には次のような問題がある。
データを提供するクラス(=データ・ソース)に複数のプロパティがあると、イベント・ハンドラの内部が煩雑になる*1。データ・ソースが増えるとイベント・ハンドラも増えていき、コード全体が煩雑になる。
*1 上のコードでclock1_PropertyChangedメソッドの引数e(PropertyChangedEventArgsクラス)には、変更されたプロパティの名前が入ってくる。複数のプロパティがある場合は、そのプロパティの名前によって分岐するコードを書くことになる。
●[実装その2]コードだけでバインドするには?
上記のイベントを使ったコードは、次のようにデータ・バインドを使って書き直せる。実はデータ・バインドとは、データの変化をイベントによって画面に反映させるコードを隠ぺいする仕掛けなのだ。
// 「デジタル時計」クラスのインスタンスprivate Clock _clock1 = new Clock();public MainPage(){ this.InitializeComponent(); …… 省略 …… // 【2】テキスト・ブロックへのバインディング var tbBind = new Binding() { Source = _clock1, Path = new PropertyPath("NowTime"), }; textClock2.SetBinding(TextBlock.TextProperty, tbBind);}
' 「デジタル時計」クラスのインスタンスPrivate _clock1 As Clock = New Clock()Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 …… 省略 …… ' 【2】テキスト・ブロックへのバインディング Dim tbBind = New Binding() With tbBind .Source = _clock1 .Path = New PropertyPath("NowTime") End With textClock2.SetBinding(TextBlock.TextProperty, tbBind)End Sub
「デジタル時計」のイベントをデータ・バインドで処理するコード(上:C#、下:VB)先ほどのコードで_clock1.PropertyChangedイベントにイベント・ハンドラをセットしていた部分が、Bindingオブジェクトの生成とテキスト・ブロックのSetBindingメソッド呼び出しに変わっている。イベント・ハンドラ内で行っていたNowTimeプロパティの値の画面への反映は、SetBindingメソッドで結び付けられたBindingオブジェクトが行ってくれる。
Bindingクラスのオブジェクトには、上のコードのように、SourceプロパティとPathプロパティを最低限指定する必要がある。ここでは、「_clock1クラスのオブジェクトをデータ・ソースとして、その『NowTime』プロパティの値をバインドする」という意味になる。このとき、Bindingオブジェクトはデータ・ソースのPropertyChangedイベントにBindingオブジェクト自体が持っているイベント・ハンドラを設定する。
SetBindingメソッドで、どのコントロールのどのプロパティにデータをバインドさせるか指定する。ここでは、「textClock2コントロールのTextProperty依存関係プロパティ(=Textプロパティ)にバインドさせる」という意味だ。
この方法では、イベント・ハンドラを使った場合の問題点は解消されている。データ・ソースやバインドするプロパティの数が増えても、分岐やイベント・ハンドラの管理は増えず、Bindingオブジェクトを作ってSetBindingメソッドを呼び出すコードを並べていくだけで済む。
また、コードによるデータ・バインドを使って時刻を表示するためのテキスト・ブロックをMainPage.xamlファイルに追加しておく(Gridコントロールに、textClock1やtextClock2をそのまま追加するときにはコントロールをStackPanelなどに格納するとよい)。
<TextBlock x:Name="textClock2" Text="00:00:00" FontSize="120" Foreground="DarkGoldenrod" />
コードによるデータ・バインドで時刻表示を行うのに使用するテキスト・ブロック(XAML)
これで先ほどのイベントを使ったコードと同様に動作する。ビルドして確かめてほしい。
●[実装その3]XAMLでバインドするには?
しかし、Bindingオブジェクトの作成とSetBindingメソッドの呼び出しのコードを記述するのは面倒だ。実はXAMLで同じことをさらに簡潔に記述できる。コントロールの「データ・コンテキスト」という場所(=DataContextプロパティ)にデータ・ソースをセットしてやると、あとはXAMLでバインドを記述することが可能だ。
まず、コードビハインドを次のように書き変える。
// 「デジタル時計」クラスのインスタンスprivate Clock _clock1 = new Clock();public MainPage(){ this.InitializeComponent(); …… 省略 …… // 【3】テキスト・ブロックのデータ・コンテキストに設定 // ※バインドはXAMLで定義する textClock3.DataContext = _clock1;}
' 「デジタル時計」クラスのインスタンスPrivate _clock1 As Clock = New Clock()Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 …… 省略 …… '【3】テキスト・ブロックのデータ・コンテキストに設定 ' ※バインドはXAMLで定義 textClock3.DataContext = _clock1End Sub
「デジタル時計」をデータ・ソースとしてテキスト・ブロックのデータ・コンテキストに設定するコード(上:C#、下:VB)ここでは、Clockクラスをインスタンス化し、そのオブジェクトがデータを提供するようになるまでの時間はごく短いので、ページのコンストラクタに記述している。実際には、ページが表示されたタイミングで非同期にデータを取得させることが多い。
これでテキスト・ブロックのデータ・コンテキストに、「デジタル時計」のインスタンスがセットされた。XAML側では、次のようにしてデータ・コンテキストを基準としたデータ・バインドを定義できる。
<TextBlock x:Name="textClock3" Text="{Binding NowTime}" FontSize="120" Foreground="DarkRed" />
時刻表示をデータ・バインドで行うテキスト・ブロック(XAML)
Textプロパティにデータ・バインドが指定されている。C#/VBのコードでBindingオブジェクトを作ったときはSourceプロパティとPathプロパティを設定したが、ここでは「NowTime」という名前だけ、つまりBindingオブジェクトのPathプロパティの値だけを指定している。省略されたSourceプロパティは、テキスト・ブロックのデータ・コンテキストと見なされる。
そして、このテキスト・ブロックのデータ・コンテキストには、C#/VBのコードでClockクラスのインスタンスを与えてあるから、結局このXAMLコードは「ClockクラスのインスタンスのNowTimeプロパティを、TextBlockコントロールのTextプロパティにバインドする」という意味になる。
このようにXAMLを使うことでデータ・バインドを簡潔に書ける。データ・コンテキストをセットしてしまえば、あとはPathプロパティを指定するだけでデータ・バインドを定義できる。しかし、内部的にやっていることは冒頭のイベント・ハンドラを使ったコードと同じで、データ・ソースのイベントをトリガにしてそのデータを画面に反映させているのだ。
●まとめ
データ・バインドとは、イベントを使ってデータの変化を画面に伝える仕掛けである*2。イベント・ハンドラを使っても同様な実装を行えるが、データ・バインドを利用した方が簡潔に記述できる。ただし、XAMLで記述する場合は「データ・コンテキストに何が入っているか?」を把握することが重要だ。なお、データ・バインドで使うデータ・ソースはINotifyPropertyChangedインターフェイスを実装していなければならない。
データ・バインドの基本について詳しくは、次のドキュメントを参照してほしい。
MSDN:データ バインドの概要MSDN:Binding マークアップ拡張MSDN:PropertyPath の構文
*2 本稿では説明しなかったが、逆向き(画面の変化→データ)もある。
「WinRT/Metro TIPS」
仮想通貨カジノパチンコおっさん ず ラブ inthesky キャスト