Silverlight 2で作成する業務アプリケーション入門(5)
WINGSプロジェクト 土井 毅 [著] 山田 祥寛 [監修] 2009/01/29 14:00

サンプルファイル 49.70 KB

 .NET Framework 3.5のWPFは強力なデータバインディングをサポートしていますが、そのサブセット的位置づけにあるSilverlight 2もやはり多彩なデータバインディングに対応しています。特に、業務アプリケーションの多くは、一般に帳票画面と呼ばれるリソースを表示・編集する画面の集合でできており、この実装においてデータバインディングは欠かせない技術と言えます。本稿ではSilverlight 2のデータバインディングの概要と業務アプリケーションへの実装について扱います。

1 2 3 4 5 6 7 →

データバインディングの概要

 データバインディングとは、ユーザーインターフェイスのプロパティと他のコントロールやクラスのプロパティを関連づける処理のことです。データバインディングは主に、データベースやWebサービスなどから取得したリソースを、クライアント上のコントロールに表示する場合などに利用します。

 データバインディングを使わない場合は、「リソースを順に取得しながら、対応するコントロールのプロパティに代入する」といったコードが必要になります。例えば、次のようなコードになります。

データバインディングがない場合のソースコードの例
var resource = getResource(); //データベースやWebサービスなどからリソースを取得
nameTextBox.Text = resource.Name;         //テキストボックスに値を代入
addressTextBlock.Text = resource.Address; //テキストブロックに値を代入

 一方、データバインディングを使えば、「このコントロールには○○というフィールドを表示させる」という設定をしておくだけで、実際の値の割り当て(=バインディング)は自動的に行われます。詳細は後で扱いますが、データバインディングがどれぐらい簡潔な記述でできるかを少し見てみましょう。XAMLコード側では次のようにコントロールと、割り当てるプロパティを関連づけます。

データバインディングを使った場合のソースコードの例(XAMLコード)
<TextBox Text="{Binding Path=Name}"  x:Name="nameTextBox"/>
<TextBlock Text="{Binding Path=Address}"  x:Name="addressTextBlock"/>

 合わせて分離コードで、バインドするオブジェクトを指定します。

データバインディングを使った場合のソースコードの例(C#分離コード)
var resource = getResource(); //データベースやWebサービスなどからリソースを取得
this.DataContext = resource;  //バインド元オブジェクトを設定

 バインドするコントロールが少ない場合は、データバインディングを使わないコードでも対応できますが、多数のコントロールを使うケースや、データ数に応じてコントロールの数を増減させる場合などは、データバインディングを使った方がずっと楽になります。

 特に、業務アプリケーションの多くは、一般に帳票画面と呼ばれるリソースを表示・編集する画面の集合でできており、この実装においてデータバインディングは欠かせない技術と言えます。

 .NET Framework 3.5のWPFは強力なデータバインディングをサポートしていますが、そのサブセット的位置づけにあるSilverlight 2もやはり多彩なデータバインディングに対応しています。本稿ではSilverlight 2のデータバインディングの概要と業務アプリケーションへの実装について扱います。

バインド元オブジェクト

 Silverlight 2におけるバインド元のオブジェクトですが、SOAP、RSS、Webサービスを経由したXMLサービスやデータベースなどさまざまなものが使えます。各種データソースをNET Framework3.5の新機能であるLINQを利用して、加工してからバインドすることも可能です。また、コード内に実データを埋め込んでおき、それをバインド元にすることもできます。

Silverlight 2のデータバインドモード

 Silverlight 2のデータバインディングには次の3つのモードがあります。

Silverlightのデータバインドモード
モード概要
OneTimeバインドされた時点のオブジェクトの値がコントロールに反映される。以後、オブジェクトの値が更新されても、コントロールは更新されない。
OneWayバインドされた時点のオブジェクトの値がコントロールに反映され、以後、オブジェクトの値が更新されるたびに、コントロールが更新される。
TwoWayOneWayに加え、コントロールの値が更新された場合にも、オブジェクトの値に反映される。

 OneTimeバインディングは固定値をバインドするモードです。バインド先でデータソースが指定された時点で一度だけバインドが実行されます。バインド後に元データが変化しても、コントロールには反映されません。データソースの更新がほとんど生じない場合はOneTimeバインドを使用するのが良いでしょう。

 OneWayバインディングはその名の通り片方向からのバインドモードで、バインド元データソースの変化にリアルタイムに対応し、バインド先の表示データが追随する形で動作します。

 TwoWayバインディングは双方向のバインドモードです。バインド元またバインド先双方からのデータ更新機能を実装したい場合に使用します。ちなみに、WPFのデータバインドではデフォルトのモードがTwoWayになっていましたが、SilverlightではデフォルトがOneWayになります。この点、WPFでの実装経験のある開発者は注意が必要です。

 なお、バインドモードとしてOneWayおよびTwoWayを使う場合には、バインドするオブジェクトはINotifyPropertyChangedインターフェイスを実装する必要があります。これはオブジェクトの値が更新されたことを検出するためのインターフェイスです。

Silverlight 2のバインド先とDataContext

 Silverlight 2では、実質的にほとんどのコントロールのプロパティをデータバインディングの対象とすることが可能です。TextBlockコントロールのTextプロパティのような、画面に表示されるプロパティにバインドするのが一般的ですが、スタイル指定のプロパティや、コントロールの位置にオブジェクトの値をバインドすることも可能です。

 バインディングを行う場合はXAMLでユーザーインターフェイスを定義する際に、{Binding …}のような特殊な構文を使用します。例えば、TextBlockコントロールのTextプロパティにバインディングで値を設定する場合は下のように記述します。

XAMLファイル内における{Binding…}構文の例
<TextBlock Text="{Binding Path=FirstName Mode=OneWay}" />

 この場合、Textプロパティに、バインド元オブジェクトのFirstNameプロパティの値がOneWayモードでバインディングされます。

 さて、今の構文においては、プロパティの種類のみが指定され、バインド元オブジェクトが明示されていないことに気づかれたかと思います。Silverlightのデータバインドは、コントロールごとに特定のバインド元オブジェクトを指定することもできますが、特に指定しない場合は親コントロールのDataContextプロパティで指定されたオブジェクトが継承されます。下にDataContextプロパティの設定例を示します。

分離コードにおけるDataContext設定の例(thisはUserControl等、親コントロールを指す)
object1.FirstName = "Hello,World!";
this.DataContext = object1;

 この記述の場合、バインド元オブジェトとしてobject1が指定されています。従って、先ほどのTextBlockにバインドされるのはobject1のFirstNameプロパティ、つまり、"Hello,World!"という文字列になります。もちろんこの例ではobject1はFirstNameプロパティを持つクラスのインスタンスでなければなりません。

 前述の通り、ユーザーコントロールのDataContextプロパティはそのユーザーコントロール以下に配置されたコントロールに継承されます。例えばGridやStackPanelといったレイアウト系のコントロールにDataContextを設定すると、それら以下のコントロールにも同様に設定したDataContextが適用されます。

 一方、データソースを指定してバインドする場合は次のように記述します。

バインド先のXAMLコードの例
<TextBlock x:Name="textBlock"
           Text="{Binding Source={StaticResource bindSource} }" /> 
<!-- //Text属性に固定ソースを指定してバインディング -->
分離コードの例
public Page()
        {
            InitializeComponent();
            string firstName= "Hello,World!";
            Binding bindSource = new Binding();
            bindSource.Source = firstName;    //バインド先に対応した型のソースを指定
            textBlock.SetBinding(textBlock.TextProperty, bindSource);
        }

 ここでは、バインド情報bindSourceにテキストデータを設定し、XAML側で固定ソースとしてバインドしています。


プロフィール
WINGSプロジェクト 土井 毅 ドイ ツヨシ

WINGSプロジェクトについて>
有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2011年7月時点での登録メンバは36名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。


プロフィール
山田 祥寛 ヤマダ ヨシヒロ

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。
主な著書に「入門シリーズ(サーバサイドAjax/XMLDB/PEAR/Smarty)」「独習シリーズ(ASP.NET/PHP)」「10日でおぼえる入門教室シリーズ(ASP.NET/PHP/Jakarta/JSP&サーブレット/XML)」「Pocket詳解辞典シリーズ(ASP.NET/PHP/Perl&CGI)」「今日からつかえるシリーズ(PHP/JSP&サーブレット/XML/ASP)」「書き込み式 SQLのドリル」他、著書多数


記事へのコメント・トラックバック機能は2011年6月に廃止させていただきました。記事に対する反響はTwitterやFacebook、ソーシャルブックマークサービスのコメントなどでぜひお寄せください。

スポンサーサイト