Hi,
ich habe eine Textbox, die an einer BindingSource hängt. In diese Textbox sollen Daten eingegeben werden und diese dann beim Drücken auf einen Speichern-Button in ein Dataset geschrieben und in einer Datenbank gespeichert werden.
Vor dem Speichern rufe ich die EndEdit-Methode der BindingSource auf, um alle Änderungen auch in das Dataset zu übernehmen.
Das Problem ist nur, wenn ich den Focus noch auf der Textbox, also gerade etwas eingegeben habe und auf Speichern klicke, wird die Textbox geleert und dementsprechend der leere String gespeichert. Ich muss vor dem Speichern erst die TextBox verlassen um die Eingabe abzuschließen.
Kann mann das auch programmtechnisch lösen? Ich hab versucht, einfach vor dem BindingSource.EndEdit() den Focus auf ein anderes zu Control setzen, bringt aber nichts.
Hallo buyden,
this.ActiveControl = this.otherControl;
this.ActiveControl = this.textBox;
this.ActiveControl = this.otherControl;
// jetzt sind sicher alle eingaben abgeschlossen.
Gruß
Juy Juka
Ich glaub, da stimmt iwas anneres nicht.
Weil wenn buyden auf den Speichern-Button klickst, ist die Textbox doch verlassen.
Oder isses ein ToolstripControl?
Der frühe Apfel fängt den Wurm.
Habs jetzt mal mittm ToolstripItem ausprobiert - kein Prob mit BindingSource.EndEdit().
Und nu?
Der frühe Apfel fängt den Wurm.
ist ein ToolStripButton.
Funktioniert aber, sobald ich das ActiveControl explizit umsetze.
this.ActiveControl = dgvVariante;
varianteBindingSource.EndEdit();
SaveTableToDatabase(dsSmd.variante);
Das gleiche Problem gab's auch bei ner ComboBox, deren SelectedValue auch nicht aktuell war.
private void tbToolbeistellungAdd_Click(object sender, EventArgs e)
{
this.ActiveControl = dgvToolbeistellung;
cmdInsert.Parameters.Clear();
cmdInsert.CommandText =
"INSERT INTO toolbeistellung " +
"(produktblatt, tool, position) " +
"VALUES (@p1, @p2, @p3)";
cmdInsert.Parameters.AddWithValue("@p1", produktblattID);
cmdInsert.Parameters.AddWithValue("@p2", cmbTool.SelectedValue);
cmdInsert.Parameters.AddWithValue("@p3", cmbPosition.SelectedValue);
try
{
SetConString();
using (conSmd)
{
conSmd.Open();
cmdInsert.ExecuteNonQuery();
conSmd.Close();
}
}
catch(Exception ex)
{
MessageBox.Show("Fehler beim Hinzufügen der Toolbeistellung \n" +
ex.Message, "Datenbankfehler");
}
Hallo, hatte das gleiche Problem und hab mir damals mit einer noch unschöneren Variante geholfen
//Funny workaround to force active edit contol to commit its changes
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("+{TAB}");
sendet einmal Tab und dann Shift-Tab um aus dem Control heraus und wieder hineinzuspringen. Dabei wird die Bindingsource aktualisiert
Die Cursorposition bleibt netterweise dabei erhalten.
Kannes sein, daß du DatagridviewTextboxColumn und Textbox, und DatagridviewComboboxColumn und Combobox in einen Topf wirfst?
Beim Datagridview muß man DGV.EndEdit() aufrufen, bevor man BindingSource.EndEdit() betätigt.
Dann braucht man auch nicht den Focus zu versetzen.
Der frühe Apfel fängt den Wurm.
@ErfinderDesRades
Nee eigentlich nicht. Es handet sich um eine stinknormale TextBox bzw. Combobox.
@rasepretrep
Ja, die is wirklich nicht sehr schön, wobei ich es auch nicht besonders sauber finde, ein anderes control active zu setzen. Es fehlt eben ein EndEdit wie bei der BindingSource.
Man kann auch ContainerControl.Validate() aufrufen. Dadurch werden alle enthaltenen Controls validiert, und da's Standard-Binding mit DataUpdateMode.OnValidating eingestellt ist, sollte das denselben Effekt haben, wie den Focus zu versetzen (wodurch ja auch die Validierung ausgelöst wird).
Hat evtl. den Nachteil, daß auch andere Controls unnötigerweise validiert werden.
Das mit sendkeys - z.B. wenn gleichzeitig die Shift-Taste gehalten wird, dürfte er nicht mehr zurück-hopfen.
Der frühe Apfel fängt den Wurm.
Es ist ganz einfach und logisch: Nicht die Binding Source beharken, sondern das Objekt, das sich hinter dem Vorhang um den Transport der Daten zwischen Binding Source und Controls kümmert: den BindingManager. Der wird automatisch beim Binden von Controls erstellt, und kann über den BindingContext des Containers (der Form i. A.) abgerufen werden:
BindingManagerBase BM = this.BindingContext[this.dataSet, "theDataTableName"];
Die noch eventuell in Editbuffern gebundener Controls hängenden Eingaben kann man dann mit
BM.EndCurrentEdit();
einsammeln und in die Binding Source schreiben lassen. Danach kann man dann problemlos die Update-Methode des DataAdapters aufrufen.
Schöne Grüße
Bass
PS: Muss nur gemacht werden, wenn die Textbox den Focus nicht verliert, also beim Update über das Menü, oder einen Toolbar Button. Bei "normalen" Buttons verliert die Textbox den Focus und schreibt den Editbuffer selber in die Data Source. Also mehr oder weniger immer 😉
BindingManagerBase BM = this.BindingContext[this.dataSet, "theDataTableName"];
Wichtig: den BindingManagerBase immer genau so holen wie man gebunden hat.
also
BindingManagerBase BM = this.BindingContext[this.dataSet, "xy"];
liefert nicht denselben BM wie:
BindingManagerBase BM = this.BindingContext[DataTablexy,null];
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Hmm also ich mache das seit dieser Thread gestartet wurde (vor über einem Jahr.. lol)
immer über einen ValidateChildren() Aufruf in der Form befor ich irgendwelche Daten speichere oder sonstwie weiterverarbeite.
das löst auf jeden Fall das oben beschriebene Problem recht gut und funktioniert generell bei Databinding auch ohne Datasets.
Wenn man keine Validierung braucht kann man auch einfach die DataSourceUpdateMode-Eigenschaft des Bindings ändern. 😉