Hallo.
entweder bin ich heute schon total neben der Kapp oder ich bin Urlaubsreif:
Ich binde eine DataTable an eine DataGridViewSource:
con = new SqlConnection(Properties.Settings.Default.MietkleidungConnectionString);
string befehl = "SELECT mt.ID, mt.PersonalID, mt.Menge, mt.KleidungsID, mt.Schluesselnummer, mt.Groesse FROM miete mt";
adapMiete = new SqlDataAdapter(befehl, con);
datatMiete = new DataTable("Verwaltung");
datatMiete.Locale = System.Globalization.CultureInfo.InvariantCulture;
adapMiete.Fill(datatMiete);
[B] cmbl = new SqlCommandBuilder(adapMiete); [/B]
dataGridViewMiete.DataSource = datatMiete;
datatMiete.PrimaryKey = new DataColumn[]{datatMiete.Columns["ID"]};
Funktioniert soweit und die Daten werden im DataGridView angezeigt.
Auch der Insert funktioniert, das mache ich über das CellValueChanges Event:
DataRow row = datatMiete.NewRow();
row[0] = ++x;
row[1] = dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value.ToString() == "" ? 2 : Convert.ToInt32(dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value);
row[2] = dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value.ToString() == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value);
row[3] = dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value.ToString() == "" ? 22 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value);
row[4] = dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString() == "" ? "112233" : dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();
row[5] = dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString() == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value == DBNull.Value ? "0" : dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString(); ;
[B]
datatMiete.Rows.Add(row);
adapMiete.Update(datatMiete);[/B]
Geht soweit.
Im selben event möchte ich nun Änderungen speichern:
\*Haltepunkt
DataRow row = datatMiete.Rows[e.RowIndex];
datatMiete.Rows[e.RowIndex][0] = x;
datatMiete.Rows[e.RowIndex][1] = dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value.ToString();// == "" ? 2 : Convert.ToInt32(dataGridViewMiete.Rows[e.RowIndex].Cells[1].Value);
datatMiete.Rows[e.RowIndex][2] = dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value.ToString();// == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value == DBNull.Value ? 0 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[2].Value);
datatMiete.Rows[e.RowIndex][3] = dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value.ToString();// == "" ? 22 : Convert.ToInt16(dataGridViewMiete.Rows[e.RowIndex].Cells[3].Value);
datatMiete.Rows[e.RowIndex][4] = dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();// == "" ? "112233" : dataGridViewMiete.Rows[e.RowIndex].Cells[4].Value.ToString();
datatMiete.Rows[e.RowIndex][5] = dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString();// == "" || dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value == DBNull.Value ? "0" : dataGridViewMiete.Rows[e.RowIndex].Cells[5].Value.ToString(); ;
// MessageBox.Show(adapMiete.UpdateCommand.CommandText);
// DataRowState state = row.RowState;
// DataTable getch = datatMiete.GetChanges();
adapMiete.Update(datatMiete);
Also ich schnappe mir den RowIndex und speichere die Änderungen im Datatable.
Das Problem hierbei ist nun, dass der RowState immer auch "unchanged" steht bzw. GetChanges = null ist.
Die Tabelle hat 6 Spalten. Ändere ich die Dritte, kann ich mir das ja anschauen im Debugger.
Haltepunkt ist auf der ersten Zeile, hier schaue ich nun in die DataTable den einen Wert an.
An dieser Stelle ist dieser aber schon eingetragen, obwohl ich die Zuweisungen noch gar nicht durchlaufen habe.
Daher ist RowState auch immer unchanged.
Doch woher kommt das? Warum ist in der DataTable der geänderte Wert schon aktualisiert, obwohl ich den erst hier zuweise?
Hallo,
die erste Frage die sich mir stellt: Warum arbeitest du nicht direkt mit DataBinding? Du kannst die ganze DataTable als DataSource an das DataGridView hängen.
Dann würden die DataRows aus der Table sicher auch direkt in den "Dirty"-Modus gehen, wenn du Änderungen innerhalb einer Zeile durchführst.
Ich habe es auch gerade mal grob getestet. Wenn ich deinen Code richtig interpretiere, hast du ja auch bereits die DataTable an das Grid gebunden. Das heißt, die Änderungen gehen Zwangsläufig in das DataTable, wenn du diese vornimmst.
Normalerweise sollte der RowState der DataTable dann auch "Modified" sein. Rufst du vor dem Update-Aufruf AcceptChanges auf?
Würdest du der MSDN folgen, wüsstest du auch, dass dein Hinzufügen / Ändern viel zu viel ist...
Folgendes kleines Beispiel:
DataTable _myData;
SqlDataAdapter _dataAdapter;
private void GetData()
{
// ... Connection und command initialisieren
_dataAdapter.Fill(_myData);
// ... commandbuilder gedöns...
myData.PrimaryKey = new DataColumn[]{myData.Columns["ID"]};
this.MyDataGridView.DataSource = _myData;
}
private void SaveChanges()
{
_dataAdapter.Update(_myData);
}
Wenn ich mich nicht täusche müsste das voll und ganz ausreichen.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Ja leider wird trotzdem nichts zurückgeschrieben...auch wenn ich es ganz minimal erstelle wie in deinem Beispiel...
Wird denn wie in meinem Beispiel gezeigt, wenigstens der Insert durchgeführt? Außerdem würde ich von "On-The-Fly" Speichern absehen und das nur auf Anforderung machen (Speichern klicken oder ähnliches).
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Guten Morgen.
Also ich mache das ganze Prozedere ja im Event CellValueChanged.
Liegt es vielleicht daran?
Irgendwie muss ich ja feststellen, ob eine Zeile oder Zelle geändert wurde und dieses abfangen und in die DB schreiben. Per Button möchte ich das nicht machen, sondern direkt bei Änderung bzw. neuer Zeile.
Habe schon etliche Events ausprobiert und das erscheint mir als das sinnvollste.
Kann es daran liegen?
EDIT: Also nach diesem Beispiel geht es, einfacher geht es nicht mehr.
Allerdings muss man dafür einen Button drücken, was oft vergessen wird. Daher hätte ich das gerne in einem Event. Welches wäre hier am sinnvollsten?
Naja,
dann müsste es analog der Variante mit dem Button-Click auch im CellValueChanged-Event funktionieren. Aus meiner Sicht sollte das gehen, da ja das Verhalten nicht anders ist.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Analog zu dem verlinkten Beispiel geht es auch nicht in diesem Event... scheint also definitiv das falsche zu sein.
Probier das ganze mal im "RowValidated"-Event.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Naja CellValueChanged bedeutet nicht das der Wert final ins DataSet geschrieben wurde.
Du musst dann schon noch ein endedit machen, damit der Wert in der DataTabloe ankommt.
Aber allgemein ist das die falsche herangehensweise. Wenn jemand schnell schreibt und nach jedem zeichen der Datensatz in die DB geschrieben wird, dann macht das nur probleme.