Frank Dzaebel, erstellt am: 26.4.2009, zuletzt geändert:
26.4.2009
Kategorie: DataGridView, .NET-Version: 3.5, [Download]
Dieser Artikel erläutert zwei Möglichkeiten zur Visualisierung
von N:M Beziehungen mit dem DataGridView. Es wird eine Technik über eine Zwischentabelle
mit zwei 1:N Beziehungen
erläutert. Zum einen wird eine Möglichkeit über LINQ-Joins dargestellt, zum anderen über die Filter-Eigenschaft des BindingSource.
- Handling 1 (über LINQ Query)
- Handling 2 (über BindingSource.Filter-Eigenschaft)


N:M Darstellung und Handling 1 (über
LINQ-Query)
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
namespace NzuM
{
public partial class MzuN_Handling1 : Form
{
public MzuN_Handling1()
{
InitializeComponent();
}
// N:M Darstellung und Handling 1 (über LINQ-Query)
// Schritte, die zur Erstellung des Projektes geführt haben:
//
// 1) Über Menü "Datenquellen anzeigen" die Personal-Tabelle in die Form ziehen.
// 2) Rechts daneben ein DataGridView einfügen und 'dgv' nennen.
// 3) Die Kunden-Tabellen (ausserhalb eines DataGridViews) hineinziehen
// und mit [Entf] Taste löschen. Das gleiche mit Bestellungen.
// 4) Den unten stehenden Quellcode einfügen.
//
// Für das "MzuN_Handling 1" in Program.cs bitte folgendes ersetzen:
// Application.Run(new MzuN_Handling1());
private void Form1_Load(object sender, EventArgs e)
{
// vom Designer automatisch angelegt:
this.kundenTableAdapter.Fill(this.personalBestellungKundeDataSet.Kunden);
this.bestellungenTableAdapter.Fill(this.personalBestellungKundeDataSet.Bestellungen);
this.personalTableAdapter.Fill(this.personalBestellungKundeDataSet.Personal);
// zugefügt:
CreateBindingHandler(personalBindingSource);
}
/// <param name="dataGridView">Der BindingSource,
/// auf dessen Änderungen reagiert werden soll.</param>
private void CreateBindingHandler(BindingSource bs)
{
bs.CurrentChanged +=new EventHandler(RefreshBinding);
bs.BindingComplete += new BindingCompleteEventHandler(RefreshBinding);
bs.ListChanged +=new ListChangedEventHandler(RefreshBinding);
RefreshQuery();
}
void RefreshBinding(object sender, EventArgs e)
{
RefreshQuery();
}
private void RefreshQuery()
{
DataRowView drv = personalBindingSource.Current as DataRowView;
PersonalBestellungKundeDataSet.PersonalRow pRow =
drv.Row as PersonalBestellungKundeDataSet.PersonalRow;
var query =
from p in personalBestellungKundeDataSet.Personal
where p._Personal_Nr == pRow._Personal_Nr
join b in personalBestellungKundeDataSet.Bestellungen
on p._Personal_Nr equals b._Personal_Nr
join k in personalBestellungKundeDataSet.Kunden
on b._Kunden_Code equals k._Kunden_Code
select new
{
// hier halt beliebig, das, was gewünscht ist:
NeuerName = p.Nachname + ", " + p.Vorname,
Versanddatum = b.Straße,
Kontaktperson = k.Kontaktperson
};
dgv.DataSource = query.ToList();
var ds = query.ToList();
}
// automatisch von Designer angelegt.
private void personalBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.personalBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.personalBestellungKundeDataSet);
}
}
}
N:M Darstellung und Handling 2 (über
Filter-Eigenschaft)
using System;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using BestellRow = NzuM.PersonalBestellungKundeDataSet.BestellungenRow;
namespace NzuM
{
public partial class MzuN_Handling2 : Form
{
public MzuN_Handling2()
{
InitializeComponent();
}
// N:M Darstellung und Handling 2(über Filter-Eigenschaft)
// Schritte, die zur Erstellung des Projektes geführt haben:
//
// 1) Über Menü "Datenquellen anzeigen" die Personal-Tabelle in die Form ziehen.
// 2) Rechts daneben ein DataGridView einfügen und 'dgv' nennen.
// 3) Die Kunden-Tabellen (ausserhalb eines DataGridViews) hineinziehen
// und mit [Entf] Taste löschen. Das gleiche mit Bestellungen.
// 4) Die Sub-Tabelle Bestellungen aus den Datenquellen in die Form ziehen
// und mit [Entf] wieder löschen, den bestellungenBindingSource in
// personalBestellungenBindingSource umbenennen.
// 4) Den unten stehenden Quellcode einfügen.
//
// Für das "MzuN_Handling 2" in Program.cs bitte folgendes ersetzen:
// Application.Run(new MzuN_Handling2());
private void MzuN_Handling2_Load(object sender, EventArgs e)
{
this.kundenTableAdapter.Fill(this.personalBestellungKundeDataSet.Kunden);
this.bestellungenTableAdapter.Fill(this.personalBestellungKundeDataSet.Bestellungen);
this.personalTableAdapter.Fill(this.personalBestellungKundeDataSet.Personal);
CreateBindingHandler(personalBestellungenBindingSource);
}
/// <summary></summary>
/// <param name="dataGridView">Der BindingSource,
/// auf dessen Änderungen reagiert werden soll.</param>
private void CreateBindingHandler(BindingSource bs)
{
bs.CurrentChanged += new EventHandler(RefreshBinding);
bs.BindingComplete += new BindingCompleteEventHandler(RefreshBinding);
bs.ListChanged += new ListChangedEventHandler(RefreshBinding);
RefreshQuery();
}
void RefreshBinding(object sender, EventArgs e)
{
RefreshQuery();
}
private void RefreshQuery()
{
BindingSource bs = personalBestellungenBindingSource;
StringBuilder filter = new StringBuilder();
foreach (DataRowView drv in bs.List)
{
BestellRow bestellRow = drv.Row as BestellRow;
if (filter.Length != 0) filter.Append(" OR ");
filter.Append("[Kunden-Code] = '" + bestellRow._Kunden_Code + "'");
}
kundenBindingSource.Filter = filter.ToString();
dgv.DataSource = kundenBindingSource;
dgv.TopLeftHeaderCell.Value = kundenBindingSource.Count.ToString();
}
// automatisch von Designer angelegt.
private void personalBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.personalBindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.personalBestellungKundeDataSet);
}
}
}