|
分類:[C#]
お世話になっております。DD.です。
BindingCompleteの動作に関してうまく把握できず困っております。ご指導願えますでしょうか。
やりたいことは、2つのテキストボックスをフォームに貼り付け、1つのユーザ定義クラスからそれらのテキストボックスへバインディングを行います。
各々BindingCompleteイベントを受け取り処理をしたいと思っています
以下がサンプルコードとなります。
public partial class Form1 : Form
{
private NameWithValue source_;
private BindingSource bindingSource_;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
source_ = new NameWithValue();
bindingSource_ = new BindingSource();
#if (false) // パターンA
Binding nameBinding = txtName.DataBindings.Add("Text", source_, "Name", true, DataSourceUpdateMode.OnValidation);
nameBinding.BindingComplete += new BindingCompleteEventHandler(BindingComplete);
Binding valueBinding = txtValue.DataBindings.Add("Text", source_, "Value", true, DataSourceUpdateMode.OnValidation);
valueBinding.BindingComplete += new BindingCompleteEventHandler(BindingComplete);
#else // パターンB
bindingSource_.DataSource = source_;
bindingSource_.BindingComplete += new BindingCompleteEventHandler(BindingComplete);
txtName.DataBindings.Add("Text", bindingSource_, "Name", true, DataSourceUpdateMode.OnValidation);
txtValue.DataBindings.Add("Text", bindingSource_, "Value", true, DataSourceUpdateMode.OnValidation);
#endif
}
private void BindingComplete(object sender, BindingCompleteEventArgs e)
{
Control c = (Control)e.Binding.BindableComponent;
MessageBox.Show(c.Name);
}
}
public class NameWithValue : INotifyPropertyChanged
{
private string name_;
private string value_;
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public string Name
{
get { return name_; }
set
{
name_ = value;
OnPropertyChanged("Name");
}
}
public string Value
{
get { return value_; }
set
{
value_ = value;
OnPropertyChanged("Value");
}
}
}
期待していた動作は、GUI上からtxtNameに入力後、BindingCompleteにはtxtNameのコントロールのみが通知される。
txtValueに入力後は、BindingCompleteにはtxtValueのコントロールのみが通知される。です。
パターンAでGUI上からtxtNameに入力を行うと、
source_.Nameへのセッター→source_.Valueへのゲッター→BindingCompleteにtxtValueコントロールが通知→BindingCompleteにtxtNameコントロールが通知
の流れとなります。
パターンAでは、"txtNameの"バインディングコレクションのTextプロパティに関するBindingを取得し、それに対するBindingCompleteにハンドラを登録しているのだから、
txtNameのTextプロパティにバインドされているsource_.Nameが更新された場合のみ、BindingCompleteにtxtNameコントロールが通知されてくるのだと思ってました。
なぜtxtNameコントロールだけでなく、txtValueコントロールも通知されてくるのでしょうか?(両者はどのように関連づいている?)
(2つのテキストボックスでBindingCompleteに登録するハンドラを別々のものに変えても同じ動作であることを確認しています。)
まだパターンBならばbindingSource_にsource_が関連づいており、そのbindingSource_自体に対するBindingCompleteにハンドラが登録されているため、
txtName及びtxtValueのどちらかを入力後に、両方のコントロールがBindingCompleteに通知されることは何となく納得できる気がします。
結局パターンAもまるで、パターンBのように各々のテキストボックス、各々のプロパティへのBindingCompleteの登録であっても、
バインドした(プロパティではなく)ソースそのものに対してバインドされているかのような動作に見えてしまいます。
参考になるURLなどもありましたら教えて頂ければと思います。
|