Laden...

Textboxeingabe beenden

Erstellt von buyden vor 15 Jahren Letzter Beitrag vor 13 Jahren 4.735 Views
B
buyden Themenstarter:in
203 Beiträge seit 2007
vor 15 Jahren
Textboxeingabe beenden

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.

2.187 Beiträge seit 2005
vor 15 Jahren

Hallo buyden,


this.ActiveControl = this.otherControl;
this.ActiveControl = this.textBox;
this.ActiveControl = this.otherControl;
// jetzt sind sicher alle eingaben abgeschlossen.

Gruß
Juy Juka

5.299 Beiträge seit 2008
vor 15 Jahren

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.

5.299 Beiträge seit 2008
vor 15 Jahren

Habs jetzt mal mittm ToolstripItem ausprobiert - kein Prob mit BindingSource.EndEdit().

Und nu?

Der frühe Apfel fängt den Wurm.

B
buyden Themenstarter:in
203 Beiträge seit 2007
vor 15 Jahren

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");
            }

R
103 Beiträge seit 2009
vor 15 Jahren

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.

5.299 Beiträge seit 2008
vor 15 Jahren

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.

B
buyden Themenstarter:in
203 Beiträge seit 2007
vor 15 Jahren

@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.

5.299 Beiträge seit 2008
vor 15 Jahren

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.

B
1 Beiträge seit 2010
vor 13 Jahren

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 😉

4.221 Beiträge seit 2005
vor 13 Jahren

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...

R
103 Beiträge seit 2009
vor 13 Jahren

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.

M
334 Beiträge seit 2007
vor 13 Jahren

Wenn man keine Validierung braucht kann man auch einfach die DataSourceUpdateMode-Eigenschaft des Bindings ändern. 😉