Leere Datensätze beim Speichern mit DataGridView unterdrücken nachdem Checkbox im Detail einer Master/Detail Relation verbunden wurde

03/05/2010 - 11:19 von microsoft.public.de.german.entwickler.dotnet.csharp | Report spam
Hi ihr,

habe eine sehr einfache Beispielanwendung geschrieben um das Problem
zu verdeutlichen und es somit einzukreisen:

Es sind zwei DataGridViews in einer Master/Detail Konfiguration (=>
das Detail DataGridView ist über eine Relation angebunden). Ihr könnt
ja die Tabellen Adresse und Person durch eine beliebige Tabelle
ersetzen um das Beispiel nachzuvollziehen.
Solange ich keine Checkbox auf die Form setze und sie nicht über ein
Binding Objekt an die Detail Binding Source (bs2) anbinde, klappt
alles wie geünscht mit dem Speichern. Wenn ich die Checkbox jedoch
anbinde, dann werden (wenn ich mit dem Cursor auf die unterste
Datenzeile des Detail DataGridView wechsle (wo man einen zu
INSERTenden Datensatz eintragen kann)) jedes mal leere Datensàtze im
DataGridView bzw. DataSet erzeugt, die dann beim Speichern natürlich
auch in die Tabelle geschrieben werden.

Hier ist der Beispielsourcecode:

using System;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;


namespace DataGridViewTestDBAnbindung
{
public partial class Form1 : Form
{
private SqlConnection con;
private DataSet ds;
private SqlDataAdapter da1;
private SqlCommandBuilder cb1;
private BindingSource bs1;
private SqlDataAdapter da2;
private SqlCommandBuilder cb2;
private BindingSource bs2;
private DataRelation dr;



public Form1()
{
InitializeComponent();



// Anbindung des SQL Servers
con = new SqlConnection("Data Source=MIB-VM-ETS;Initial
Catalog=PIS;Integrated Security=True;");
con.Open();
da1 = new SqlDataAdapter("select * from person", con);
da2 = new SqlDataAdapter("select * from adresse", con);
cb1 = new SqlCommandBuilder(da1);
cb2 = new SqlCommandBuilder(da2);
ds = new DataSet();
da1.Fill(ds, "Person");
da2.Fill(ds, "Adresse");
bs1 = new BindingSource();
bs2 = new BindingSource();



bs1.DataSource = ds;
bs1.DataMember = "Person";



dr = new DataRelation("Rel",
ds.Tables["Person"].Columns["PersonID"],
ds.Tables["Adresse"].Columns["PersonID"]);
ds.Relations.Add(dr);



bs2.DataSource = bs1;
bs2.DataMember = "Rel";



dataGridView1.DataSource = bs1;
dataGridView2.DataSource = bs2;



//dataGridView1.DataMember = "Firma";
bindingNavigator1.BindingSource = bs1;
bindingNavigator2.BindingSource = bs2;



Binding bcheckBox1 = new Binding("Checked", bs2, "Test");
checkBox1.DataBindings.Add(bcheckBox1);
}



private void button1_Click(object sender, EventArgs e)
{
// Speichern
this.Validate();
dataGridView1.EndEdit();
dataGridView2.EndEdit();
bs1.EndEdit();
da1.Update(ds, "Person");
bs2.EndEdit();
da2.Update(ds, "Adresse");
MessageBox.Show("Gespeichert!");
}



private void button2_Click(object sender, EventArgs e)
{
// Abbrechen
dataGridView1.CancelEdit();
bs1.CancelEdit();
dataGridView2.CancelEdit();
bs2.CancelEdit();
MessageBox.Show("Abgebrochen!");
}
}
}

=> Irgendwie wird also durch die angebundene Checkbox jedes mal ein
Leersatz generiert, wenn man mit dem Cursor auf die letzte Zeile des
DataGridViews fàhrt und zurück. Wahrscheinlich, weil das Objekt keinen
Null Zustand seiner Checked Eigenschaft kennt? Denn wenn ich es mit
der Eigenschaft Text anbinde, werden keine Leerdatensàtze erzeugt. Wie
kann ich nun elegant es vermeiden, dass jedes mal Leerdatensàtze
erzeugt werden, wenn ich versehentlich auf die letzte Datenzeile
komme?

Any Hints?

Mit freundlichem Gruß,
Christoph Rall
 

Lesen sie die antworten

#1 Marcel Roma
03/05/2010 - 16:40 | Warnen spam
Hallo Christoph,

Am Mon, 3 May 2010 02:19:29 -0700 (PDT) schrieb
microsoft.public.de.german.entwickler.dotnet.csharp:

Solange ich keine Checkbox auf die Form setze und sie nicht über ein
Binding Objekt an die Detail Binding Source (bs2) anbinde,
*klappt alles wie gewünscht mit dem Speichern*.



Damit es nun *wirklich* klappt mit dem Speichern, mußt Du noch die
MissingSchemaAction setzen bevor Du die Methode Fill() aufrufst:

da1.MissingSchemaAction = MissingSchemaAction.AddWithKey;
da2.MissingSchemaAction = MissingSchemaAction.AddWithKey;

So wissen die DataAdapter-Instanzen, dass sie sich um die Primàrschlüssel
kümmern und die Primàr- und Fremdschlüsseleinschrànkungen der Datenquelle
nachbilden müssen. Ohne gültige Schemainformationen sind Duplikatzeilen
vorprogrammiert.

s.a.: Hinzufügen vorhandener Einschrànkungen zu einem DataSet
http://msdn.microsoft.com/de-de/library/49z48hxc(VS.80).aspx


Gruss
Marcel Roma

Ähnliche fragen