連載
» 2012年12月21日 14時51分 公開

XAML/Silverlightでデータ バインディング連載:次世代技術につながるSilverlight入門(3/3 ページ)

[岩永信之,著]
前のページへ 1|2|3       

データ・フローの向き

 BindingオブジェクトのModeプロパティによって、データ・フロー(=データの受け渡しの流れ)の向きを設定できる。以下の3種類の向きがある*1

  • OneWay: ソースが変化した際に、データをターゲットに反映する(既定)
  • TwoWay: ソースとターゲットの双方で、データの変更を他方に反映する
  • OneTime: データ・バインディングを行った瞬間のみ、ソースのデータをターゲットに反映する

*1 WPFの場合にはもう1つ、「OneWayToSource」という、ターゲットからソースへの向きがある。


 ただし、データの変更をターゲットに反映させるためには、ソース側に変更通知の仕組みが必要になる。以下のいずれかである。

  • ソース側が依存関係プロパティの場合、何もしなくても、DependencyObjectが変更通知を行ってくれる
  • CLRオブジェクトの通常のプロパティの場合、変更通知を行うには、INotifyPropertyChangedインターフェイス(System.ComponentModel名前空間)を適切に実装する必要がある(実装方法の例については次回説明予定)

 TwoWayモードでのデータ・バインディングを行う際には、UpdateSourceTriggerプロパティによって、ソース側を更新するタイミングを、以下のいずれかから選択できる。

  • Default: テキストボックスの場合のみ、フォーカスが離れた瞬間にソースを更新する。そのほかの場合はプロパティ値が変化した瞬間
  • PropertyChanged: プロパティ値が変化した瞬間に(テキストボックスの場合は、キー入力のたびに)ソースを更新する
  • Explicit: 自動的にはソースを更新しない。BindingExpressionクラス(System.Windows.Data名前空間。FrameworkElementクラスのGetBindingExpressionメソッドを使って取得)のUpdateSourceメソッドを明示的に呼びだしたときにだけソースを更新する

データの変換

 ソースから得た値をそのままターゲットに渡すのではなく、何かしらの変換をかけてから渡したい場合もあるだろう。よくある例でいうと以下のようなものがある。

  • bool値のtrue/falseに応じて、Visibilityを切り替える*2
  • true/falseを反転する
  • true/falseに対してYes/Noなどの文字列を表示する
  • の輝度や彩度を変える
  • 角度を度数(degree)から弧度(radian)に変更する

 このような場合に使うのがコンバータだ。

*2 Windowsストア・アプリの場合、Visual Studioのプロジェクト・テンプレートにBooleanToVisibilityConverterクラス(=bool値に応じたVisibility切り替え)とBooleanNegationConverterクラス(=true/false反転)が初めから含まれている


コンバータの作成

 コンバータの実体は、IValueConverterインターフェイス(System.Windows.Data名前空間)を実装したオブジェクトである。例えば、先ほど例に挙げた、true/falseを反転するコンバータは、リスト 10のようなコードで作成できる。

using System;
using System.Globalization;
using System.Windows.Data;
 
namespace TemplateSample.Common
{
  public class BooleanNegationConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return !(value is bool && (bool)value);
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return !(value is bool && (bool)value);
    }
  }
}


Imports System.Globalization
Imports System.Windows.Data

Namespace Global.TemplateSample.Common

  Public Class BooleanNegationConverter
    Implements IValueConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
      Return Not (TypeOf (value) Is Boolean AndAlso CType(value, Boolean))
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
      Return Not (TypeOf (value) Is Boolean AndAlso CType(value, Boolean))
    End Function

  End Class

End Namespace


リスト 10: コンバータの作成例(上:C#、下:VB)


 IValueConverterインターフェイスの2つのメソッドは、Convertがソースからターゲットにデータを渡す際の変換、ConvertBackがターゲットからソースへの書き戻しの際の変換となる。

コンバータの利用

 作成したコンバータは、Bindingオブジェクトの以下のプロパティを使って参照する。

  • Converter: コンバータ本体を設定する
  • ConverterParameter: コンバータに渡すパラメータ(リスト 10中のコードでいうparameterに渡される)
  • ConverterCulture: コンバータに渡すカルチャー(リスト 10中のコードでいうcultureに渡される)

 例えばリスト 11に示すように、リソース中で定義したものを参照して使う。

<UserControl
  x:Class="TemplateSample.Views.ConverterSampleControl"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:common="clr-namespace:TemplateSample.Common">

  <UserControl.Resources>
    <common:BooleanNegationConverter x:Key="negate" />
  </UserControl.Resources>
 
  <StackPanel>
    <CheckBox x:Name="check1" Content="Source" />
    <CheckBox Content="Target" IsChecked="{Binding IsChecked, ElementName=check1, Mode=TwoWay, Converter={StaticResource negate}}" />
  </StackPanel>

</UserControl>


リスト 11: コンバータの利用例(XAML)


データ検証

 データ・バインディングには、エンド・ユーザーから入力されたデータの検証を行う機能が備わっている。どういう検証を行うかは、Bindingオブジェクトの以下のプロパティを使って設定する。

  • ValidatesOnNotifyDataErrors: INotifyDataErrorInfoインターフェイス(System.ComponentModel名前空間)を使ったデータ検証を行う*3
  • ValidatesOnDataErrors: IDataErrorInfoインターフェイス(System.ComponentModel名前空間)を使ったデータ検証を行う
  • ValidatesOnExceptions: コンバータや、プロパティのsetアクセサで例外が発生したときに検証エラー扱いにする
  • NotifyOnValidationError: 検証エラーが起きたときに、FrameworkElementクラスのBindingValidationErrorイベントを発生させる

*3 Silverlight 4からの機能。WPFでは、ValidatesOnDataErrorsは当初から、ValidatesOnNotifyDataErrorsは4.5からの対応。Windowsストア・アプリには同様の仕組みはない。


 データの変更通知と同様に、ソース側のオブジェクトにデータ検証コードを組み込む必要がある(INotifyDataErrorInfoインターフェイスを使った実装方法の例を次回説明予定)。

 Silverlightのテキストボックスなどのコントロールは検証エラー時用のスタイルを定義していて、検証エラーがあるときには図 5に示すような外観の変化/ポップアップ表示が行われる。

図 5: データ検証エラー時のスタイルの例

そのほかのプロパティ

 そのほか、Bindingオブジェクトは以下のようなプロパティを持っている。

  • StringFormat: 数値などを単純に文字列化して表示したいときに、書式を指定する
  • TargetNullValue: 値が「null」(C#の場合。VBでは「Nothing」)のときに表示する値
  • FallbackValue: データ・バインディングに失敗したとき(=パスが見つからないときなど)に表示する値

 次回はデータ・バインディングとデータ・テンプレートを使ったデータの表示や、INotifyPropertyChangedやINotifyDataErrorInfoインターフェイスを使ったデータの更新通知/検証について説明していく。

「連載:次世代技術につながるSilverlight入門」のインデックス

連載:次世代技術につながるSilverlight入門

前のページへ 1|2|3       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。