Frank Dzaebel, erstellt am: 21.1.2008, zuletzt geändert:
21.1.2008
Kategorie: Datenbindung, .NET-Version: 2.0/3.5, [Download]
OO-Design, wie Subklassen bei der Datenbindung ihre Eltern-Klassen
informieren können (CurrentItemChanged),
damit diese (zum Beispiel) ihre Ansicht aktualisieren können.
Ein typisches Mittel ist die INotifyPropertyChanged-Schnittstelle.
Spart man sich diese Schnittstelle, ist ggf. ein
ResetCurrentItem als Workaround möglich.
using System;
using System.Data;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
namespace BindingListChanged
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
BindingList<Person> personen = new BindingList<Person>();
BindingSource bs;
private void Form1_Load(object sender, EventArgs e)
{
FülleDaten(personen);
bs = new BindingSource();
bs.DataSource = personen; dgv.DataSource = bs;
bs.CurrentItemChanged +=new EventHandler(bs_CurrentItemChanged);
dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgv.Columns["PrivatAnschrift"].ReadOnly = true;
textBox1.DataBindings.Add("Text", bs, "Name");
textBox2.DataBindings.Add("Text", bs, "Alter");
textBox3.DataBindings.Add("Text", bs, "PrivatAnschrift.Strasse");
foreach (Control tb in tlPanel1.Controls)
if (tb is TextBox)
tb.TextChanged += new EventHandler(tb_TextChanged);
}
int counter = 0;
void tb_TextChanged(object sender, EventArgs e)
{
ZeigeEreignis("TextChanged");
if (MitResetCurrentItem())
bs.ResetCurrentItem(); // <<-- Workaround, wenn ohne INotifyPropertyChanged
}
private bool MitResetCurrentItem()
{
return !chkReset.Checked;
}
void bs_CurrentItemChanged(object sender, EventArgs e)
{
ZeigeEreignis("CurrentItemChanged");
}
private void ZeigeEreignis(string ereignis)
{
txtInfos.AppendText(String.Format("{0}:{1}\r\n", counter++,ereignis));
txtInfos.ScrollToCaret();
}
private void FülleDaten(BindingList<Person> personen)
{
personen.Add(new Person(42, "Alpha", new Anschrift("A Strasse 1")));
personen.Add(new Person(21, "Beta", new Anschrift("B Strasse 2")));
personen.Add(new Person(53, "Gamma", new Anschrift("G Strasse 3")));
personen.Add(new Person(19, "Delta", new Anschrift("D Strasse 4")));
}
class Person : INotifyPropertyChanged
{
public Person(int alter, string Name, Anschrift privatAnschrift)
{
this.Alter = alter;
this.name = Name;
this.privatAnschrift = privatAnschrift;
this.privatAnschrift.PropertyChanged += new PropertyChangedEventHandler(privatAnschrift_PropertyChanged);
}
void privatAnschrift_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyPropertyChanged("PrivatAnschrift");
}
private int alter;
public int Alter
{
get { return alter; }
set { alter = value; }
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private Anschrift privatAnschrift;
public Anschrift PrivatAnschrift
{
get { return privatAnschrift; }
set
{
privatAnschrift = value;
NotifyPropertyChanged("PrivatAnschrift");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
class Anschrift : INotifyPropertyChanged
{
public Anschrift(string strasse)
{
this.strasse = strasse;
}
private string strasse;
public string Strasse
{
get { return strasse; }
set
{
strasse = value;
NotifyPropertyChanged("Strasse");
}
}
public override string ToString()
{
return strasse;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
private void chkReset_CheckedChanged(object sender, EventArgs e)
{
chkReset.Text = (chkReset.Checked ? "Ohne" : "Mit") + " ResetCurrentItem";
}
}
}