C# WPFのバインディング その1

WPFではMVVMという概念で開発する。

MVVMとは、Model,View,ViewModelという3つの部分に分けて設計・実装するというもの。

 

データやそれを加工するロジックを担当するのが「Model」。

そのデータを適した形で表示し、入力を受け付けるUIの部分が「View」。

双方の受け渡しを担当するのが「ViewModel」。

 

これらを分離する事で、保守性(それぞれの設計がシンプルに)や生産性(プログラマとデザイナーで分担できる)が良くなるという考え方。

このViewModelの部分を担当する1つがバインディングという仕組み。

以下のような例を考えてみる。 

 

上から順にTextBox、TextBlock、Buttonが並んでいる。

TextBoxとTextBlockは同じ「SampleText」というデータにバインドされている。

また、Bottonがクリックされるとデータ「SampleText」の値を書き換える処理がされている。


       ↓

 

 

TextBoxへ書き加えた状態。

TextBoxを書き変えるとバインドされたデータ「SampleText」が更新される。

「SampleText」が更新されると同様にバインドしたTextBlockの表示も書き変わる。

 


       ↓

 

 

Buttonをクリックした状態。

ButtonのClickイベントでデータ「SampleText」の値を

「ボタンがクリックされました」に書き変えている。

 

「SampleText」が更新されるとバインドしたTextBoxとTextBlockの表示が書き変わる。

 


<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="180" Width="250">
    <StackPanel Margin="20">
        <TextBox Text="{Binding SampleText}"/>
        <TextBlock Text="{Binding SampleText}"/>
        <Border Height="20"/>
        <Button Content="Text変更" Click="Button_Click"/>
    </StackPanel>
</Window>
public class SampleData
{
    public string SampleText { get; set; }
}
    public partial class MainWindow : Window
    {
        private SampleData Data;


        public MainWindow()
        {

            InitializeComponent();

            Data = new SampleData();
            Data.SampleText = "サンプルテキスト";
            DataContext = Data;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Data.SampleText = "ボタンがクリックされました";
        }
    }

TextBoxのTextプロパティとTextBlockのTextプロパティが{Binding SampleText}となっている。

これは「SampleText」という名前のデータフィールドへバインドするという意味。

 

「SampleText」というデータフィールドを持つデータクラスは各コントロールのDataContextプロパティにセットされる。のだがDataContextになにもセットされていなかったら、その親のコントロールのDataContextを参照。そこもセットされていなかったら、更に親を参照していく。

 

 

上記の例では、TextBoxやTextBlockのDataContextにはなにもセットせず、一番親のMainWindowのDataContextへデータクラスをセットしている。(13行目)

 

 

 

更に、バインディングを正しく使う為に以下の仕組みを知っておく必要がある。

 バインディングのモード

 プロパティの変更通知

 

 

つづく

 

 

コメントをお書きください

コメント: 2
  • #1

    かきそふと (月曜日, 12 3月 2018 10:22)

    分かりやすい説明、ありがとうございます!

    SampleDataクラスの定義が抜けていたので、以下のソースを追加して実行してみました。
    =============
    public class SampleData
    {
    public string SampleText { get; set; }
    }
    =============

  • #2

    AraramiStudio (月曜日, 12 3月 2018 13:08)

    かきそふとさん
    コメントありがとうございます。
    SampleDataクラスの定義が足りていなかったので本文もに追記しました。
    ご指摘ありがとうございました。