Löschen von Zeilen im DataGrid - Indexproblem

Eichhoernchen09

Grünschnabel
Hallo!

Ich habe folgendes Problem, bei dem ich dringend Hilfe suche: :(

Ich habe einen Dialog, der Daten aus einer Datenbank lädt und sie in einem DataGrid und verschiedenen Textfelder (über DataBinding) anzeigt. Nun kann man hier beliebig editieren, Einträge hinzufügen oder löschen (über Schaltflächen, nicht über das Grid, das ist schreibgeschützt). Das Problem ist nun, dass ich beim Löschen einer Zeile über den CurrentRowIndex gehe und das DataGrid mit den Indizes durcheinander kommt. Lösche ich zum Beispiel die vierte Zeile und danach die Fünfte, behauptet es, kommt ein Fehler, dass ich auf gelöschte Zeileninformationen zugreife. Wie kann ich über den Index des DataSets, das dem DataGrid zu Grunde liegt, löschen? Für Webanwendungen hab ich da im Forum die Eigenschaft DataSetIndex gesehen, aber ich arbeite hier mit WindowsForms und habe noch keine passende Eigenschaft gefunden.

Hier mein Quelltext:

BEIM LADEN DES DIALOGES:
Code:
m_data=ds;	//globales DataSet bekommt DataSet aus Datenbank zugewiesen
m_view = m_data.Tables[0].DefaultView;	//View erstellen
this.dataGrid.DataSource = m_view;	//View als DataSource zuordnen
//Daten binden
this.idBox.DataBindings.Add(new Binding("Text",m_view,"ID"));
…

private void dataGrid_CurrentCellChanged(object sender, System.EventArgs e)
{
//hier ermittle ich die letzte ausgewählte Zeile, um sie später zu 
//löschen oder zu kopieren (m_row ist global)
	if(m_row!=null) 
		m_row.EndEdit();
	//aktuelle Zeile
	m_row = m_data.Tables[0].Select(m_filter)[grd.CurrentRowIndex];
		
}//end methode


KLICK AUF DIE SCHALTFLÄCHE ZUM LÖSCHEN:
Code:
if(m_data!=null)
{
//Löschen, wenn eine Zeile ausgewählt wurde
//Der State wird nur wegen des oben beschriebenen Fehlers abgefragt
if(m_row!=null && !m_row.RowState.Equals(DataRowState.Deleted)) 
	{													m_row.Delete();
}					
}//end if

Also, wie bekomme ich es hin, das er die richtigen Zeilen aus dem DataSet und DataGrid löscht und nicht mit den Indizes durcheinander kommt? :confused:

Vielen Dank schon mal im Voraus!
 
Ohne deinen Code gross anzusehen würde ich zwei Dinge in betracht ziehen:
-Nach dem Löschen DataGrid neu laden damit nur noch die Aktuellen Werte drin sind?
-Du machst aus der Funktion "Löschen" einfach ein Visible = false, und am Schluss, wenn du denkst du bist fertig, sprich wenn du das Programm schliesst, löschts du alle Datensätze die Visible = false sind aus deinem Datagrid

Wobei ich meinen zweiten Vorschlag gerade als Sinnlos sehe und absoluten Quatsch :D

Naja ich persönlich hab nie versucht die Daten aus dem DataGrid zu löschen, da das DataGrid ja nur ne Abbildung von den Daten deiner DB ist. Also, Werte direkt in der DB änder, löschen etc und nacher immer wieder das DG neu laden nach einer Änderung in der DB..

MFG

ziop
 
Hallo Eichhoernchen!
Hi Ziop!
Eichhoernchen09 hat gesagt.:
Lösche ich zum Beispiel die vierte Zeile und danach die Fünfte, behauptet es, kommt ein Fehler, dass ich auf gelöschte Zeileninformationen zugreife.
Kann es sein das nur 5 drinn waren? Dann ist es logisch. Wenn Du das vierte löschst,
gibt es keinen fünften Datensatz mehr. Der ist dann an die Stelle der vierten gerutscht.
Mehrere Rows nacheinander via Indexer zu löschen ist nicht besonders sinnvoll.
Du müsstest die Indexer nach dem Löschen anpassen. (rowIndex--)
Hol Dir einfach die Referenzen der Rows, die kannst in eine Liste temporär ablegen.
Geh die Liste durch und verwende halt DataRow.Delete()

Es ist sicher einfacher direkt mit der DB zu agieren und danach wieder zu aktualisieren.
Das kann aber auch Probleme in sachen Performace während des bearbeitens herrvorrufen
und man hat vielleicht mal schneller was geändert als es eigentlich gewollt war...

P.S: Ziop, Du alter Blödeleienschreiber ;-] :D
 
Zuletzt bearbeitet:
Hallo und danke für Eure Antworten!

Das mit vier und fünf Zeilen war nur ein Beispiel. Es sind mehr Zeilen vorhanden.
Und die aktuellen Werte sind im DataGrid vorhanden, denn die Zeile wird ja entfernt.

Ich will schon in dem DataSet und nicht in der Datenbank arbeiten, denn die Änderungen am DataSet sollen erst anschließend komplett in die Datenbank übernommen werden.
Das Problem ist, dass das DataSet bei row.Delete() die Zeile nicht löscht, sondern nur als gelöscht markiert. Das hat zur Folge, dass die Zeile noch da ist und den selben Index hat. Lösche ich also z.B. Zeile 4, rutscht Zeile 5 hoch, hat dann den Index von Zeile 4 und so greift er intern wieder auf Zeile 4 zu, die bereits gelöscht ist.

Ich habe das nun folgendermaßen gelöst:

statt
Code:
row.Delete()
habe ich
Code:
m_data.Tables[0].Rows.Remove(row);
benutzt.

Somit entfernt er die Zeile komplett aus dem DataSet und markiert sie nicht nur als gelöscht. Die IDs der Zeilen speichere ich in ein Array und lösche dann später alle Zeilen mit diesen IDs aus der Datenbank.

Das kann man nur machen, wenn man nicht den RowState Delete benutzt, um nach gelöschten Zeilen zu fragen und den DataAdapter für ein automatisches Delete ausführt.
Das ist für andere Anwendungen natürlich schade. Aber bei mir funktioniert dieser Weg nun! :)
 
Zurück