WPFのコードビハインドとデータバインディングの関係

コンピュータ

WPFではUIを構築する方法として、
コードビハインドによるイベントドリブン
データバインディングという2つの考え方があります。

この2つは対立するものではなく、役割が異なる仕組みです。

また、どちらか一方だけでもアプリケーションを作成することは可能です。

ただしWPFは、ある程度規模の大きいアプリケーション開発で採用されることが多いため、
そのようなケースではロジックとUIを分離する目的で
データバインディングを中心とした設計が採用されることがあります。

では、コードビハインドは全く不要かと言うと、
残念ながらそうでもありません。

UIを操作する細かな動作など、
Viewの内部で完結させるべき処理も数多く存在します。

例えば次のようなものです。

  • UIコントロールの細かな状態制御
  • フォーカス操作
  • レイアウト調整
  • ドラッグ操作などのマウスイベント処理
  • View固有の表示ロジック

これらはアプリケーションロジックではなく、
純粋にUIの振る舞い

そのため、このような処理まで
データバインディングだけで解決しようとすると、
本来UIに属する処理がViewModel側へ流れ込み、
設計が歪んでしまう

このようなケースでは、
コードビハインドで処理を書く方が自然な設計になります。

WPFの基本構造

  • Viewの見た目部分は XAML で静的コンテンツとして作る
  • Viewの振る舞いは コードビハインド(C#) で作る

この構造はWebに例えると以下のような関係になります。

  • XAML → HTML / CSS の役割
  • C#コードビハインド → JavaScript の役割

つまり、WPFのUIは XAML + コードビハインド だけでも
完結したアプリケーションを作ることが可能です。

コードビハインドによるイベントドリブン

WPFの基本的なプログラミングモデルはイベントドリブンです。

  • ウィンドウやコントロールでイベントが発生する
  • コードビハインドでイベントハンドラを書く
  • 対応する処理を実行する

例えばボタンが押された場合は次のようになります。


private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Hello WPF");
}

また、コードビハインドでは以下のようなことも自由に行えます。

  • コントロールの動的生成
  • コントロールの追加・削除
  • UI構造の変更

ただし、このような動的UI操作は後述するデータバインディングと相性があまり良くありません。

データバインディングの役割

アプリケーションロジックやビジネスロジックを
UIから分離して管理したい場合に使われるのが
データバインディングです。

データバインディングは次の仕組みです。

  • XAMLのプロパティ
  • C#クラスのプロパティ

この2つを自動的に連動させる仕組みです。


Text="{Binding UserName}"

この場合、C#側には次のようなプロパティが存在します。


public string UserName { get; set; }

バインディングは名前で接続される

WPFのバインディングは
名前(文字列)で接続されます。

つまり次のような構造です。

  • XAML → “UserName”
  • C# → UserName プロパティ

ここで重要なのは、
お互いが直接参照しているわけではないという点です。

XAMLは単なる文字列としてプロパティ名を書いており、
WPFのバインディングシステムが実行時に接続しています。

そのため、XAMLとC#は互いの存在を直接知らない構造になっています。

DataContextとバインディング元

バインディングのデータソースは通常
WindowのDataContextになります。


this.DataContext = new MainWindowViewModel();

DataContextには通常のC#クラスのオブジェクトを指定できます。

ただし、UIを自動更新するには
INotifyPropertyChangedを実装する必要があります。


public class ViewModel : INotifyPropertyChanged

これにより、プロパティが変更されたときにUIへ通知されます。

ICommandによるアクションのバインディング

ボタンのクリックなど、
ユーザー操作をトリガーに処理を実行したい場合
データバインディングでは ICommand を使います。

特徴的なのは、
処理なのにメソッドではなくプロパティとして扱う点です。


public ICommand SaveCommand { get; }

XAML側


Button Command="{Binding SaveCommand}"

このようにすることで、
ボタン操作とC#側の処理をバインディングで接続できます。

まとめ

  • WPFのUIは XAML + コードビハインド で完結する
  • 基本モデルはイベントドリブン
  • ロジックをUIから分離したい場合はデータバインディングを使う
  • バインディングは名前(文字列)で接続される
  • DataContextがデータソースになる
  • アクション処理はICommandとしてプロパティで公開する

コードビハインドとデータバインディングは
どちらか一方だけを使うものではなく、目的に応じて使い分ける仕組みです。

WPFではこの2つを理解することで、
UI設計の自由度が大きく広がります。

コメント