SP1適用完了!!
ということで、WPF関連で追加された機能の1つBindingGroupを試してみようと思う。
その前に、軽くBindingGroupの説明を見てみると「複数のBindingをまとめてやるよ!」っていう感じのことが書いてあった。バリデーションとかもうまいこと面倒見てやるからありがたいだろう。といった感じっぽい。ってことで、ありがちなダイアログボックスにテキストボックスがいくつかあって、色々編集してOKを押すと値が適用される。Cancelを押すと変更した内容は無かったことになる。といった感じのものを作るのが楽になりそうな機能だ。
いきなり色々やると収集がつかなくなりそうなので、とりあえず単純に使ってみようと思う。
まず、バインドするためのクラスを作る。いつもどおりPersonという名前のクラスを作った。
namespace BindingGroupSample
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
// 確認用
public override string ToString()
{
return "[Person Name: " + Name + ", Age: " + Age + "]";
}
}
}
そして、XAML側はこんな感じにしてみた。
<Window x:Class="BindingGroupSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BindingGroup Sample Application" Height="129" Width="326">
<Window.BindingGroup>
<BindingGroup />
</Window.BindingGroup>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="3"
Text="名前:" />
<TextBlock Grid.Row="1" Grid.Column="0" Margin="3"
Text="年齢:" />
<TextBox Grid.Row="0" Grid.Column="1" Margin="3"
Text="{Binding Name}" />
<TextBox Grid.Row="1" Grid.Column="1" Margin="3"
Text="{Binding Age}" />
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Alert" MinWidth="50" Margin="3" Click="AlertButton_Click" />
<Button Content="Apply" MinWidth="50" Margin="3" Click="ApplyButton_Click" />
<Button Content="Cancel" MinWidth="50" Margin="3" Click="CancelButton_Click" />
</StackPanel>
</Grid>
</Window>
一番上のほうにあるWindow.BindingGroupの所が、今回の目玉のBindingGroupになる。
FrameworkElementに追加されたBindingGroupプロパティに、BindingGroupのインスタンスを設定してる。これで、多分Window以下のBindingがグループ化されてそうな雰囲気だ。
後はWindowのDataContextにさっきのPersonクラスのインスタンスを突っ込むとテキストボックスにデータが表示されるようになる。
下にある3つのボタンに、BindingGroupの操作とDataContextの中身の確認を書いていく。ということで、Window1.xaml.csはしたのような感じに書いた。
using System.Windows;
using System.Windows.Data;
namespace BindingGroupSample
{
/// <summary>
/// Window1.xaml の相互作用ロジック
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new Person
{
Name = "田中 太郎",
Age = 18
};
}
private void AlertButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(DataContext.ToString());
}
private void ApplyButton_Click(object sender, RoutedEventArgs e)
{
BindingGroup.CommitEdit();
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
BindingGroup.CancelEdit();
}
}
}
コンストラクタで、Personクラスのインスタンスを作って、適当な値で名前と年齢を設定した。AlertButton_Clickでは、DataContextの中身をToStringして表示している。
ApplyButton_Clickは、BindingGroupのCommitEditを呼び出して、BindingGroupに対して値を書き戻すように指示している。これで、テキストボックスに入力した値がDataContextに入っているPersonオブジェクトに書き戻される。
CancelButton_Clickで、値をロールバックしている。
ということで早速実行!
実行直後は、普通にデータが表示されるだけ。Alertを押しても特にびっくりすることはない。
ここからが、BindingGroupの特徴的な動きになる。年齢の部分を100に変更してAlertを押してみた。下の結果を見るとわかるけど、BindingGroup使わないときだと年齢が100に書き換えられるはずなのにBindingGroupを使うと書き換えられない。
じゃぁ書き換えられるのは何時?ってことになるけど、これはBindingGroupのCommitEditを呼んだときになる。つまり、このサンプルだとApplyボタンを押したときってことになる。ということでApplyを押してからAlertを押してみた。
ちゃんと書き換わってる。
Cancelボタンで呼び出してるCancelEditは、編集開始時点のデータに巻き戻してくれる。ためしに年齢が100になってる部分を1に変更してからCancelボタンを押してみた。
Cancelをぽちっとな→
きちんと変更前の値に戻ってるのがわかると思う。
簡単にBindingGroupをつかってみた感想。こいつは便利そうだ。