SMTP Zugangsdaten im Programm speichern

  • VB.NET

Es gibt 74 Antworten in diesem Thema. Der letzte Beitrag () ist von DerSmurf.

    Neu

    Ja, fast. Denn an sich brauchst Du das AcceptChanges ja nicht. Nur eben, wenn die Möglichkeit besteht, dass man alternativ auch RejectChanges aufrufen könnte. Aber vielleicht ist das der Plan und ich schlussfolgere aufgrund des kleinen Codesnippets falsch.
    Nochmal allgemein zusammengefasst der Ablauf.
    1. tDS ist leer; dies ist der Anfangszustand
    2. Daten werden ins tDS laden → würde man tDS.HasChanges() aufrufen, käme True zurück
    3. AcceptChanges für ne DataTable X aufrufen* → Status 1 wird als Ist-Zustand für X registriert; würde man X.HasChanges() aufrufen, käme False zurück (weil die Änderungen von 1 auf 2 "akzeptiert wurden")
    4. X inhaltlich verändern → X ist nun in Status 2
    5. entscheiden, ob man die Datenänderung akzeptieren (AcceptChanges → Status 2 wird als Ist-Zustand für X registriert) oder verwerfen möchte (RejectChanges → X wird wieder in den Status 1 zurückversetzt)
    * aber nur, wenn Punkt 5 eine Rolle spielt!

    Letztenendes könnte man das AcceptChanges/RejectChanges mit dem Command²- oder Memento-Pattern vergleichen. Vielleicht ist das sogar die praktische Umsetzung eines der Patterns für's tDS.

    ² hier bzgl. Undo-Funktionalität

    ##########

    zur Deinem Edit: Solange Du Dein DataBinding bei Deinen Edit-CEs auf Never hast, brauchst Du AcceptChanges und RejectChanges wohl nicht. Nur eben, wenn Du Änderungen vorgenommen hast und diese rückgängig machen willst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    Neu

    Hallo nochmal.
    Sorry, aber ich begreife es nicht ganz.
    Also Accept- und RejectChanges brauche ich nicht.

    Aber wie ich die Daten in mein DataSet schreibe raffe ich nicht.

    VB.NET-Quellcode

    1. Private Sub BTNSaveOrder_Click(sender As Object, e As EventArgs) Handles BTNSaveOrder.Click
    2. Dim SelectedOrder = DirectCast(DirectCast(DTOrdersBindingSource.Current, DataRowView).Row, DtsSettings.DTOrdersRow)
    3. SelectedOrder.Net7 = Double.Parse(Net7TextBox.Text)
    4. SelectedOrder.Note = NoteTextBox.Text
    5. ' nur ein Test DtsSettings.DTOrders.Rows.Add(SelectedOrder)
    6. End Sub


    Mit diesem Code wird nur der erste Eintrag von SelectedOrder ins DataSet geschrieben.
    Also im obigen Beispiel Net7 und nicht Note. Tausche ich die Net7 und Note Zeile, wird nur Note ins DataSet geschrieben und eben nicht mehr Net7.

    Eigentlich verstehe ich überhaupt nicht, warum im DataSet etwas verändert wird (ich dachte Anfangs dafür wäre des AcceptChanges, was ich zu Beginn im Code hatte).
    ABER Dim SelectedOrder = DirectCast(DirectCast(DTOrdersBindingSource.Current, DataRowView).Row, DtsSettings.DTOrdersRow) erstellt doch ein neues Objekt der DataRow (also ist das doch quasi eine Kopie).
    Wo ist hier mein Denkfehler? Also warum landen die Daten im DataSet? Und warum nur der zuerst eingetragene Wert?
    Ich müsste doch eigentlich erstmal die Row (SelectedOrder) ans DataSet übergeben.
    Wenn ich dies aber tue und testweise eine neue Row erstellen will DtsSettings.DTOrders.Rows.Add(SelectedOrder), behauptet meine IDE diese wäre schon vorhanden. Liegt das evtl. an der Primärschlüsselspalte Namens ID, die ich nicht verändert habe?
    Also habe ich mal geschaut, was mit DtsSettings.DTOrders.Rows. noch zu anzustellen ist, aber ich habe nichts gefunden, wo ich meine SelectedOrder als Parameter übergeben kann.
    Also habe ich keinen Plan, wie ich meine Daten aus den Textboxen ins DataSet bekomme -.-

    Neu

    DerSmurf schrieb:

    Tausche ich die Net7 und Note Zeile, wird nur Note ins DataSet geschrieben.
    Dann liegt ein Programmfehler vor. Das passiert bei mir nicht. Ich kann alle Properties einer DataRow bearbeiten und die werden alle übernommen.

    DerSmurf schrieb:

    Eigentlich verstehe ich überhaupt nicht, warum im DataSet etwas verändert wird (ich dachte Anfangs dafür wäre des AcceptChanges, was ich zu Beginn im Code hatte).
    Wieso? Du manipulierst doch den tDS-Inhalt ganz aktiv.

    DerSmurf schrieb:


    ABER Dim SelectedOrder = DirectCast(DirectCast(DTOrdersBindingSource.Current, DataRowView).Row, DtsSettings.DTOrdersRow) erstellt doch ein neues Objekt der DataRow (also ist das doch quasi eine Kopie).
    Aber es verweist auf die selbe Datenzeile. Ich kann auch 5 Variablen diese Datenzeile zuordnen. Und egal, bei welcher Variable ich den Inhalt der Datenzeile ändere, beeinflusst es immer alle anderen Variableninhalte, da alles auf das selbe verweist/zielt/zeigt. Bedenke: Die BindingSource hat einen direkten Draht zur dahinterliegenden DataTable und somit zum tDS. Und wenn Du das Current der BS änderst, ändert sich der tDS-Inhalt. Das ist ja der Sinn der BS-Sache! Und daher kannst Du diese Row auch nicht dem tDS bzw. seiner DataTable hinzufügen, denn da ist sie ja schon drin. Du manipulierst eine Zeile aus der DataTable. Punkt. Keine Kopie, keine neue Zeile, sondern die eine echt vorhandene. Du greifst über die BS auf diese eine Zeile zu und manipulierst sie. Selbst wenn keine ID-Spalte da wäre, dürfte das (Wieder-)Hinzufügen nicht funktionieren. Wäre die ID das Problem, hieße es später nur, dass es eine ConstraintException gibt, weil ID in zwei Zeilen nicht gleich sein darf.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Alles klar, kapiert.

    VaporiZed schrieb:

    Dann liegt ein Programmfehler vor. Das passiert bei mir nicht. Ich kann alle Properties einer DataRow bearbeiten und die werden alle übernommen.


    Den Fehler habe ich glaube ich gerade durch Einzelschritt gefunden.
    Der Wert Net7 im DataSet hat den Wert "23", der Wert Note lautet "Notiz".
    So wird es mir auch in den beiden dazugehörigen Textboxen angezeigt.
    Nun ändere ich die TBNet7 in 10 und TBNotiz in "abc"
    Es läuft folgender Code:

    VB.NET-Quellcode

    1. Private Sub BTNSaveOrder_Click(sender As Object, e As EventArgs) Handles BTNSaveOrder.Click
    2. 1. Dim SelectedOrder = DirectCast(DirectCast(DTOrdersBindingSource.Current, DataRowView).Row, DtsSettings.DTOrdersRow)
    3. 2. SelectedOrder.Net7 = Double.Parse(Net7TextBox.Text)
    4. 3. SelectedOrder.Note = NoteTextBox.Text

    Wenn ich im Enzelschrittmodus zu Beginn (Stop in Zeile 1) über ​NoteTextBox,Text fahre, wird mir "abc" angezeigt.
    Nach der Code aber Zeile 3 erreicht hat, also nach dem abarbeiten von Zeile 2, ändert sich dieser Wert in "Notiz".

    Das heißt doch, dass sich nach dem ersten Schreiben ins DataSet, mein Binding an die Eingabetextboxen "eneuert".
    Es werden meine neu gemachten Einträge, durch die vorhandenen ersetzt und entsprechend nur der erste Wert im DataSet geändert.
    Muss ich nun das Binding an meine Textboxen "manuel setzen". Also die anzuzeigenden Daten nach einem Klick ins Datagridview aus em DataSet pulen, oder gibt es Code, oder Einstellung, um eine Aktualisierung der Bindings unterdrückt?

    Neu

    Davon ausgehend, dass bei beiden TextBoxen beim DataBinding Datenquellen-Aktualisierungsmodus auf Never steht: Hau mal als letzte Zeile noch dazu: DTOrdersBindingSource.ResetCurrentItem()
    Wenn das nix bringt, poste ich n Testprojekt, wo es klappt.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Huhu.
    Nein, die Zeile ändert nichts.

    Ich habe mal ein Screenshot meiner Form, und des DataSet angehängt.
    Nicht, dass ich noch irgendwas im Projekt habe, was du wissen solltest.
    Hab noch nichts an der Formatierung geändert, also nicht über Benennung und Optik wundern.

    Den Lieferanten hohle ich mir wie von dir vorgeschlagen mit using und .neueFormBinding.Position = .HauptformBinding.Position.
    Das auf der Hauptform dargestellte Binding an die Orders, kommt aus der SupplierBindingSource.
    Aso das mit Pfeil markierte, habe ich auf die Form geschmissen, einmal als Detail und einmal als Datagridview.

    Edit: Achja, das Datenquellen-Aktualisierungintervall steht auf Never - habe ich gerade noch einmal geprüft.

    Edit2: Würdest du überhaupt mit einem Speichern Button arbeiten? Oder die Validierung der Daten in eins der Key Events der Boxen schmeißen und das DataBinding so setzen, dass die Daten automatisch ins DataSet kommen?
    Ich habe den speichern Button erstmal nur gemacht, weil er in meinem VBA Programm auch da ist.
    Bilder
    • Anmerkung 2019-06-20 151130.png

      33,63 kB, 1.168×711, 15 mal angesehen
    • Anmerkung 2019-06-20 173918.png

      21,47 kB, 412×702, 11 mal angesehen
    • 123.png

      18,39 kB, 300×565, 10 mal angesehen

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „DerSmurf“ ()

    Neu

    Nope, da kann ich momentan nicht weiterhelfen. Da muss irgendwas in Deinem Code sein, was dem Ganzen eine Linie auf die Abrechnung malt. Daher mein Testprojekt anbei. Die Textboxen sind beide an die BS "mit Never gebunden"

    zu Deinem Edit2: Boah, das ist benutzerabhängig. Wenn man mehrere Programme geschrieben hat, sollte man sich einfach nur eine Variante angewöhnen und diese beibehalten. Denn wenn in einem Programm mit [Speichern] ist, beim nächsten mit Key-Events und beim 3. mit 2-Wege-DataBinding, dann kriegt der User doch die totale Macke.
    Dateien
    • WindowsApp1.zip

      (23,16 kB, 4 mal heruntergeladen, zuletzt: )
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Guten Abend lieber @VaporiZed
    Vielen Dank für dein Testprojekt. Aber dieses funktioniert nicht. Das Aktualisierungsintervall der angehängten Datei steht auf "onvalidation". Daher kann ich die Daten problemlos aus den Textboxen ins DataSet übernehmen, aber ich kann mir den speichern Button sparen.
    Wenn ich das Aktualisierungsintervall auf Never stelle, wird durch Klick auf speichern nur Net7 gespeichert.
    Aber eigentlich bin ich ja auch doof.
    Ich speichere einen Wert ins DataSet, dies ändert sich, alle Bindings werden aktualisiert - so soll es ja sein.
    Nur sind alle meine Änderungen in den Textboxen, dann eben weg, bzw. die alten Werte.
    Aber es ist ja eh sinnbefreit, das DataSet direkt mit Werten aus den Textboxen zu befüllen.
    Die Werte gehören ja validiert und in Variablen gepackt und dann, wenn alle Einträe i.O. sind ins DataSet.

    VB.NET-Quellcode

    1. Private Sub BTNSaveOrder_Click(sender As Object, e As EventArgs) Handles BTNSaveOrder.Click
    2. Dim SelectedOrder = DirectCast(DirectCast(DTOrdersBindingSource.Current, DataRowView).Row, DtsSettings.DTOrdersRow)
    3. Dim net7 As Double = Double.Parse(Net7TextBox.Text)
    4. Dim note As String = NoteTextBox.Text
    5. SelectedOrder.Net7 = net7
    6. SelectedOrder.Note = note
    7. End Sub

    So wird der Wert aus NoteTextBox nicht mit dem alten Wert aus dem DataSet überschrieben und alles läuft.

    Neu

    Argh. Du hast doppelt recht. Bzgl. meines falsch eingestellten Programms und der Erklärung.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Hallo @VaporiZed
    Ich muss das Thema leider noch einmal aufgreifen, denn es gibt noch eine Sache, die nicht klappt. Ich glaube weil ich etwas falsch eingestellt habe. Es geht um die Auswahl der Lieferanten.
    Diese lade ich wie folgt:

    VB.NET-Quellcode

    1. Private Sub TSNewOrder_Click(sender As Object, e As EventArgs) Handles TSNewOrder.Click
    2. LoadSupplier()
    3. If SupplierBindingSource.Current Is Nothing Then Exit Sub
    4. Dim SelectedSupplier = DirectCast(DirectCast(SupplierBindingSource.Current, DataRowView).Row, DtsSettings.SupplierRow)
    5. Dim order As DtsSettings.OrderRow
    6. 'und weiterer Code
    7. End sub
    8. Private Sub LoadSupplier()
    9. Using SupplierSelect As New frmSupplierSelect()
    10. SupplierSelect.DtsSettings = Me.DtsSettings
    11. SupplierSelect.SupplierBindingSource.DataSource = Me.DtsSettings
    12. SupplierSelect.ShowDialog(Me)
    13. SupplierBindingSource.Position = SupplierSelect.SupplierBindingSource.Position
    14. End Using
    15. End Sub​

    Die hier geladene Form hat ein Datagridview, eine Combobox und einen Button (DialogResultOK).
    Sowohl Dgv als auch ComboBox (Datenaktualisierung - Never, damit keine neuen Lieferanten angelegt werden können) sind an die DataTable Supplier gebunden.
    Auswahl des Lieferanten aus dem Dgv funktioniert.
    AUSWAHL aus der Combobox funktioniert auch - aber nur Auswahl, nicht reinschreiben des Lieferantennamens.
    Also gehen wir davon aus, es gibt die Lieferanten LF1 und LF2.
    Wenn ich nun die Form lade, ist F1 bereits ausgewählt, SCHREIBE ich in die Combobox LF2, ändert sich die SupplierBindingSource.Position nicht. Ich müsste LF2 aus dem Combobox Dropdown auswählen.
    Auch gibt es keine Autovervollständigung der Eingabe.
    Kann ich beides mit Einstellungen realisieren, oder muss ich da mit Code ran?

    Neu

    Ich hab meine ComboBoxen immer auf DropDownList, sodass man da gar nix eintragen, sondern nur auswählen kann.

    DerSmurf schrieb:

    Sowohl Dgv als auch ComboBox (Datenaktualisierung - Never, damit keine neuen Lieferanten angelegt werden können) sind an die DataTable Supplier gebunden.
    Aber schon so, oder:

    Wenn das so eingestellt ist, ist ein Datenaktualisierungsmodus nicht (bei mir) einstellbar. Es ist immer aktiv - eben weil es direkt an die BindingSource gebunden ist. D.h. Änderungen in der ComboBox-Position ändern auch die BS-Position. Sobald ich da einen Eintrag ausgewählt habe, ändert sich auch die BS-Position. Bei mir sehe ich auch sofort im DGV die Positionsveränderung. Und wenn ich etwas in die ComboBox eintrage, was nicht in der BS/DataTable drinsteht, passiert einfach auch nix. Nix an der BS-Position, nix am DataTable-Inhalt.
    Das Autovervollständigen musst Du schon selber einstellen:

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Huhu
    Mist, dass mit der AutoComplete der Combobox habe ich vergessen. Dies passiert in VBA immer von alleine.
    Das klappt nun, habe es auf Append, statt Suggest, aber ist ja wurscht.
    Die Combobox tut nun, nachdem ich den korrekten Wertemember eingestelt habe (ID ist ja eigentlich logisch) auch.
    Das Datenquellen-Aktualisierungsintervall, kann ich aber unter Eigenschaften der Combobox --> Databinding --> Erweitert nach wie vor einstellen. Dies habe ich aber einfach auf never gelassen. Damit ich nicht Gefahr laufe irgendwann mal versehentlich einen neuen Lieferanten zu haben.

    Also alles in allem, klappts. Und ich danke dir mal wieder :o)

    Neu

    Na Moment mal. Das klingt aber n bisken nach doppeltem DataBinding. Eine ComboBox, die an die BS so angebunden wird, wie in Post#72 gezeigt, hat keinen einstellbaren Datenaktualisierungsmodus! Nicht, dass Du einfaches und komplexes DataBinding (versehentlich) drin hast und dann endest wie ich einst. Im Anhang der Sollzustand. Doppeltes DataBinding lässt manchmal Effekte entstehen, mit denen man nicht rechnet. Also Obacht!
    Bilder
    • CbxDataBinding.png

      61,45 kB, 1.403×510, 5 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    Danke für den Tipp.
    In den Eigenschaften --> Databinding --> Text war noch eine Datenquellen eingebunden.
    Das meinst du ja bestimmt mit doppeltem Binding.
    Ist nun raus, und jetzt ist auch das Datenquellen Aktualisierungsintervall ausgegraut.