しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

BindingGroup を使ってみた

WPF 3.5 SP1 で追加された BindingGroup を使ってみました。以下サンプルコード。

C#

using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = new Item();
            BindingGroup.BeginEdit();
        }

        private void SubmitButton_Click(object sender, RoutedEventArgs e)
        {
            BindingGroup.CommitEdit();
            BindingGroup.BeginEdit();
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            BindingGroup.CancelEdit();
            BindingGroup.BeginEdit();
        }
    }

    public class Item : INotifyPropertyChanged
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        private int _price;

        public int Price
        {
            get { return _price; }
            set
            {
                _price = value;
                OnPropertyChanged("Price");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

XAML

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="165" Width="300" Loaded="Window_Loaded">
    <Window.Title>
        <MultiBinding StringFormat="{}{0} - {1}">
            <Binding Path="Name"/>
            <Binding Path="Price"/>
        </MultiBinding>
    </Window.Title>
    <Window.BindingGroup>
        <BindingGroup/>
    </Window.BindingGroup>
    <Grid Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="90*" />
            <ColumnDefinition Width="188*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="35*" />
            <RowDefinition Height="35*" />
            <RowDefinition Height="57*" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0" Grid.Row="0" Text="Name" VerticalAlignment="Center" />
        <TextBlock Grid.Column="0" Grid.Row="1" Text="Price" VerticalAlignment="Center" />
        <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=Name}" VerticalAlignment="Center" />
        <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Price}" VerticalAlignment="Center" />
        <StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Width="60" VerticalAlignment="Center" Click="SubmitButton_Click">Submit</Button>
            <Button Width="60" Margin="3,0,0,0" VerticalAlignment="Center" Click="CancelButton_Click">Cancel</Button>
        </StackPanel>
    </Grid>
</Window>

入力されたアイテムの名前と値段をタイトルバーに表示するという非常に簡単なサンプルですが、実行してみると Window.BindingGroup の動きがわかると思います。
Item クラスはプロパティの変更通知を実装しているので、プロパティの値が変化すると即座にタイトルバーの表示が変わるはずですが、このサンプルは Submit ボタンをクリックしないと値が反映されません。あと、値を入力した後に Cancel ボタンをクリックすると元の値に戻ったりします。
これが BindingGroup の基本的な機能で、名前の通りバインディングをグループ化して 1 つのバインディングのように扱えるようになります。サンプルでもわかるようにダイアログで活用できそうな機能です。
他にもデータの検証機能も持ちますが、簡略化のため今回は使っていません。