C# のコードでデータ バインディング (1)

XAML 系の開発で利用するデータ バインディングの仕組みを理解しやすくするため、
XAML ではなく C# のコードで、かつ、なるべく少ないコードでデータ バインディングを実装する例を示します。

まず、データ バインディングは 2 つのオブジェクトのプロパティの値を同期するための仕組みで、
その 2 つのオブジェクトのうち、主に一次的なデータとなるほうを Binding Source、
主に UI などで二次的に反映されるほうを Binding Target と呼びます。
そして 2 つのプロパティを関連付けるために、
System.Windows.Data.Binding オブジェクト (WPF の場合) を使います。

Binding には Mode プロパティ (BindingMode 列挙体) があり、どちらの方向に値を反映させるかを指定します。
次の種類があります。実際には、OneWay か TwoWay を使うことが多いでしょう。

  • OneTime: 初期化時の 1 回のみ、Source を Target に反映
  • OneWay: Source を Target に反映
  • OneWayToSource: Target を Source に反映
  • TwoWay: 双方向に反映
  • Default: Binding Target のプロパティのメタデータで定義された既定のモード (BindsTwoWayByDefault プロパティ)
    例えば、TextBlock.Text では OneWay、TextBox.Text では TwoWay です。

次に、Binding Target と Binding Source の満たすべき条件です。

  • Binding Target
    • DependencyObject (プロパティは DependencyProperty)
  • Binding Source (任意のオブジェクトだが、次のいずれかに該当する)
    • INotifyPropertyChanged
    • DependencyObject (プロパティは DependencyProperty)
    • その他の任意のオブジェクト
      プロパティ変更通知ができないため、Target への反映は初期化時の 1 回のみです。
      ただし、実際には特殊な動作をします。→ C# のコードでデータ バインディング (4) 

DependencyObject クラスは主に UI で使われるものであり、
データ モデルには通常 INotifyPropertyChanged インターフェイスを実装させます。

 

さて、ここからコードを書いていきますが、
プラットフォームは .NET のコンソール アプリケーションとし、
WPF のライブラリを参照して使うことにします。
したがって、Visual Studio でプロジェクトを作成したら、次のアセンブリを参照に追加します。

  • PresentationCore
  • PresentationFramework
  • System.Xaml
  • WindowsBase

まず、Binding Source となる Person クラスを定義します。
全部で 3 種類あり、Person0 はプレーンなクラス (POCO)、
Person1 は INotifyPropertyChanged インターフェイスを実装したクラス、
Person2 は DependencyObject クラスを継承したクラスとしました。

 

では、Main メソッドで OneWay のバインディングを実装してみます。
Person1.Name を TextBlock.Text に反映するだけの例です。
なお、TextBlock などの UI コントロールは UI スレッドでなければインスタンス化できないため、
Main メソッドに STAThread 属性を付けておきます。

データ バインディングを設定するには、
FrameworkElement.SetBinding メソッドまたは BindingOperations.SetBinding メソッドを呼び出します。

Person0 を使うとプロパティ変更通知が効かないため、最後の変更が反映されません。
Person2 の場合は、Person1 と同様に変更が反映されます。

次に、TwoWay のバインディングも実装してみます。
ここでは TextBlock の代わりに TextBox を使っています。

TextBox.Text は既定で TwoWay のため、Binding.Mode で明示的に指定しなくても TwoWay になります。
これで、Person1.Name と TextBox.Text の値が双方向に同期されます。

もちろん TextBlock を使った場合でも、

Mode = BindingMode.TwoWay

を指定すれば双方向で変更が反映されます。

 

次回: C# のコードでデータ バインディング (2)

作成したサンプル
BindingConsole (GitHub)

バージョン情報
C# 6.0
.NET Framework 4.5

参照
データ バインディングの概要
方法 : コードでバインディングを作成する
プロパティ変更とエラー情報の通知 (実装編)

コメント / トラックバック4件 to “C# のコードでデータ バインディング (1)”

  1. C# のコードでデータ バインディング (2) | Do Design Space Says:

    […] C# のコードでデータ バインディング (1) では、 プロパティの変更通知を利用したデータ […]

  2. ExpandoObject を使ったデータ バインディング | Do Design Space Says:

    […] C# のコードでデータ バインディング (1) では、 INotifyPropertyChanged インターフェイスを実装した Person1 クラスに プロパティを定義してデータ バインディングを構成しました。 […]

  3. プロパティ変更をタイマーで同期して通知する | Do Design Space Says:

    […] C# のコードでデータ バインディング (1) で書いた通り、 Binding Source は INotifyPropertyChanged か DependencyObject でなければ プロパティ変更通知ができないため、永続的に値が反映される OneWay バインディングはできません。 […]

  4. C# のコードでデータ バインディング (4) | Do Design Space Says:

    […] C# のコードでデータ バインディング (1) の中で Binding Source の条件について書きましたが、 INotifyPropertyChanged でも DependencyObject でもないオブジェクトの場合は少し難解な動作をします。 というのも、プロパティ変更通知ができないはずのオブジェクトに対して、 内部で PropertyDescriptor を経由して双方向のバインディングができるように試みるためです。 […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。