Mitgliederverwaltung - Hilfe bei der Erstellung sauberen Codes

  • VB.NET
  • .NET 4.5

Es gibt 215 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    DerSmurf schrieb:

    Aber wenn ich die einkaufrow vorher fertig mache und mit .editcurrent Anzeige, ist sie ja bereits gespeichert.
    "Gespeichert" ist bisserl übertrieben.
    Sie ist ins Dataaset übernommen - gespeichert ist ja erst, wenn Dataset.WriteXml, oder wenn an DB gesendet.

    DerSmurf schrieb:

    Könntest du mir kurz erklären, warum meine Variante (mit Übergabe der PersonRow) schlecht ist?
    Ich hab gedacht, das würde Probleme machen mit der Übergabe.
    Und die Anzeige der EinkaufRow mit all ihren ChildRows stelle ich mir mit Databinding auch sehr komfortabel zu designen vor.
    Aber wenn das auch mit einer übergebenen PersonRow ebenso einfach zu bewerkstelligen ist - warum nicht?

    ErfinderDesRades schrieb:

    Ich hab gedacht, das würde Probleme machen mit der Übergabe.

    Nein überhaupt nicht. Ich bin mir nur nicht sicher, ob ichs richtig mache, bzw. ob das was ich mache im Sinne des Erfinders ist (siehe Frage 2)

    ErfinderDesRades schrieb:

    Und die Anzeige der EinkaufRow mit all ihren ChildRows stelle ich mir mit Databinding auch sehr komfortabel zu designen vor.

    ist ja bei mir auch. Ich brauche nur eine gefilterte BS an die Artikel (IsChoosen = True) und muss die Labels mit Kundendaten an die Property binden. Das passt schon.
    Also alles gut - lassen wir bei der PersonRow und kommen zu Frage Nummer2:

    Wenn ich mit meiner oben geposteten Lösung die frmFinishOrder anzeige, wird der korrekte Kunde (die richtige PersonRow) angezeigt.
    Öffne ich die frmFinishOrder im Anschluss erneut, mit einem anderen frmVerkauf.BsPerson.Current, wird mir auf der frmFinishOrder wieder die PersonRow vom ersten mal angezeigt.
    Gleiches habe ich bei einer Checkbox auf frmFinishOrder. Diese ist im Designer auf Visible=False.
    Im Load Event prüfe ich dann: CBDatenschutz.Visible = Dts.Artikel.Any(Function(x) x.IsChoosen AndAlso x.Bezeichnung = "DAV Neuanmeldung")und lasse sie ggf anzeigen. Hier verhält es sich genauso.
    Die Visible Property ist bei jeder Anzeige der frmFinishOrder so, wie sie es bei der ersten Anzeige dieser Form war.
    Mir ist klar, dass ich beide Probleme mit einem anderen Aufruf (und eben einer Instanzierung der frmFinishOrder) lösen kann:

    VB.NET-Quellcode

    1. Private Sub FinishOrder()
    2. Dim rwPerson = BSPerson.At(Of PersonRow)
    3. Dim FinishOrder As New frmFinishOrder
    4. With FinishOrder
    5. .SetrwPerson = rwPerson
    6. .ShowDialog()
    7. End With
    8. End Sub


    Aber wie löse ich das Problem, wenn ich die Form als MdiChild angezeigt haben möchte?
    Ist das hier dann die richtige Lösung? (es funktioniert, aber @tragl sagte eine Instanzierung sei nicht notwendig. Jedoch tauchen ja hier gerade die gleichen Probleme auf, die auch auftreten, wenn ich nicht die MDI Geschichte benutze und meine Forms nicht vor dem Anzeigen instanziere. Deswegen bin ich verwirrt.

    VB.NET-Quellcode

    1. Private Sub FinishOrder()#
    2. Dim rwPerson = BSPerson.At(Of PersonRow)
    3. Dim FinishOrder As New frmFinishOrder
    4. With FinishOrder.
    5. SetrwPerson = rwPerson
    6. .ShowMdiChild
    7. End With
    8. End Sub

    DerSmurf schrieb:

    sagte eine Instanzierung sei nicht notwendig

    aber du instanziierst doch -> Zeile 3

    mal ohne probiert?
    Im Übrigen: Bei Dialogen:

    VB.NET-Quellcode

    1. Using dlg As New frmFinishOrder
    2. dlg.SetrwPerson = rwPerson
    3. If dlg.showdialog() <> Dialogresult.OK Then Return
    4. 'ggf. weiteren Code ausführen, wenn DialogResult OK war
    5. End Using

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    DerSmurf schrieb:

    Wenn ich mit meiner oben geposteten Lösung ...
    Da "oben" sind so viele Lösungen gepostet... - kannst du genauer angeben, was du meinst? Am liebsten einen aktuellen Code-Auszug - ich gehe immer davon aus, dass in Threads geposteter Code nach wenigen Tagen so nicht mehr existiert.

    DerSmurf schrieb:

    Öffne ich die frmFinishOrder im Anschluss erneut, mit einem anderen frmVerkauf.BsPerson.Current, wird mir auf der frmFinishOrder wieder die PersonRow vom ersten mal angezeigt.
    Nanu? Ich denk, du übergibst die PersonRow? Wie kann er dann eine anzeigen, die er das letzte Mal übergeben bekommen hatte?

    ErfinderDesRades schrieb:

    - ich gehe immer davon aus, dass in Threads geposteter Code nach wenigen Tagen so nicht mehr existiert.

    Nachdem ich hier was poste, höre ich auf weiterzumachen, damit so etwas nicht passiert.

    tragl schrieb:

    aber du instanziierst doch -> Zeile 3
    mal ohne probiert?

    Ja, ich habs ohne probiert, dann tritt das oben beschriebene Verhalten auf. Sauber laufen tuts nur mit instanzierung.

    Also ich lad die Solution mal hoch. Man sieht das "Fehlverhalten" wenn man folgendes tut:
    Ich wähle auf der frmVerkauf den Kunden Achim Meyer aus und packe einmal DAV Marke Erwachsen in den Warenkorb, es wird automatisch der Artikel DAV Neuanmeldung hinzugefügt.
    Dann klick auf abschließen. Dahinter ist folgender Code:

    VB.NET-Quellcode

    1. Private Sub FinishOrder()
    2. Dim rwPerson = BSPerson.At(Of PersonRow)
    3. frmFinishOrder.SetrwPerson = rwPerson
    4. frmFinishOrder.ShowMdiChild
    5. 'Dim FinishOrder As New frmFinishOrder
    6. 'With FinishOrder
    7. ' .SetrwPerson = rwPerson
    8. ' .ShowMdiChild
    9. 'End With
    10. End Sub

    Es wird die frmFinsihOrder angezeigt.
    Hier gibt es eine Checkbox (CBDatenschutz). Diese ist im Designer auf Visible = False. Im FormLoad Event wird dann folgendes geprüft:
    CBDatenschutz.Visible = Dts.Artikel.Any(Function(x) x.IsChoosen AndAlso x.Bezeichnung = "DAV Neuanmeldung")
    und die Checkbox entsrechend angezeigt, oder eben nicht. In diesem Fall wird sie natürlich angezeigt.
    Wenn ich nun den zurück Button betätige (Code: frmVerkauf.ShowMdiChild) und den Kunden Hans Hansi auswähle, wird der Artikel DAV Neuanmeldung entfernt und DAV Verzug hinzugefügt.
    Ein erneuter Klick auf abschließen und es wird in der frmFInsihOrder die Checkbox angezeigt (obwohl die Bedingung false ist) und als Kunde wird Achim Meyer angezeigt.
    Durch Einzelschritt habe ich festgestellt, dass das Form Load Event nur im allerersten Aufruf von frmFinishOrder.ShowMdiChild erreicht wird. Bei allen weiteren Anzeigen feuert das LoadEvent nicht.
    Instanziere ich die frmFinishOrder vor dem Anzeigen, läuft alles wie es soll.

    Daher stellt sich mir die Frage:
    Ist die Instanzierung dann der richtige Weg? Oder gibt es einen Weg die frmFinishOrder zu "töten"? (es funktioniert mit der Instanzierung, aber @tragl sagte dies sei nicht notwendig. Jedoch tauchen ja hier gerade die gleichen Probleme auf, die auch auftreten, wenn ich nicht die MDI Geschichte benutze und meine Forms nicht vor dem Anzeigen instanziere. Deswegen bin ich verwirrt.
    Dateien

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

    Kein Problem, nur Verwirrung.

    Denn nach meiner Frage in Post 148:
    Außerdem habe ich noch eine Frage: Warum muss ich mit der MDI Geschichte hier die Forms vorher nicht initialisieren? (hier meine ich natürlich instanzieren)

    kam von @VaporiZed die eindeutige Antwort (Post 149):
    Du hast recht: Weil an der Stelle genau mit dem Dreck gearbeitet wird, den man eben nicht nutzen sollte: thread-dependent-properties (s. Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen). Du solltest dringend dort den Dir bekannten Instanziierungsvorgang vornehmen.


    Von dir @tragl kam dazu dann in Post160 die Antwort:
    wird nicht instanziiert - funzt aber so, denn das Form wird einmal geöffnet und in jedem Fall wieder geschlossen. Ein doppeltes Öffnen geht damit nicht, sondern es wird ja hingewechselt falls es schon offen ist.


    Verwirrung entsteht bei mir nun, da ich nicht weiß, was denn jetzt stimmt.

    Neu

    Alles klar. Aber bitte verzeih - ich hab dann noch eine Verständnisfrage.
    Wenn ich eine Form instanziiere und mittels .show, oder .showdialog aufrufe, wird diese Instanz doch zerstört, sobald die angezeigte Form geschlossen wird.
    Das passiert ja hier nicht. Wenn ich 10 mal die frmFinishOrder öffne, habe ich doch auch 10 Instanzen dieser Form, die dann erst beim schließen des Programmes zerstört werden, oder habe ich hier einen Denkfehler?

    Das ist jetzt bei diesem Mini Programm hier wahrscheinlich wurscht, aber ich habe vor im Anschluss an das Projekt hier mein MainProjekt auf MDI umzustellen.
    Kann es hier nicht zu Problemen kommen, wenn das Programm den ganzen Tag läuft und irgendwann 100te Form Instanzen existieren?

    Sollte ich da nicht beim verlassen einer Form / bzw. beim Anzeigen einer neuen Form, die aktuelle irgendwie töten?

    Neu

    Alles klar. Ich danke dir!
    Dann mache ich mich mal ran, alle Aufrufe mit initialisiierung umzuschreiben.

    und hier kanns weitergehen :o)

    Wenn ich ein DGV mit Daten habe, so ist standardmäßig die erste Zeile ausgewählt.
    An machen Stellen in anderen Programmen unterbinde ich dies mit: ​ArtikelDataGridView.ClearSelection()
    Hier in diesem Programm führe ich den Code im FromLoad Event der frmFinishOrder aus, aber die erste Zeile des entsprechenden DGV ist trotzdem selektiert. Ich vermute daher, dass dies an den Helpers, oder dem Template was hier benutzt wird liegt.
    Wie kann ich da Abhilfe schaffen?

    Neu

    Hmm, nagut. Machen wir einfach die nächste Frage.
    Ich habe auf meiner frmFinishOrder sowohl KeyDown, als auch KeyPress Event abonniert:

    VB.NET-Quellcode

    1. Private Sub frmFinishOrder_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    2. MessageBox.Show("KeyDown Event")
    3. End Sub
    4. Private Sub frmFinishOrder_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
    5. MessageBox.Show("Keypress Event")
    6. End Sub


    Wenn ich die Form "normal" also mittels .show anzeige, funktioniert alles wie gewohnt. Beide Key Events werden aufgerufen.

    Zeige ich die form innerhalb meines MDI Containers wird kein Key Event erreicht.
    Woran könnte das liegen?

    Edit: Gerade habe ich festgestellt, dass beide Event gefeuert werden, wenn ich auf der Form in eine Textbox schreibe. Ohne diese (also beim anwählen eines anderen Controls) aber nicht.
    Dateien
    • Angelmarken10.zip

      (332,15 kB, 1 mal heruntergeladen, zuletzt: )

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

    Neu

    Jo, die Textbox ist dann wahrscheinlich nicht automatisch das aktive control.
    Bei mir hab ich das so gelöst (ist auch eine Textbox) auf der Childform:

    VB.NET-Quellcode

    1. Private Sub frm_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    2. tbSuche.Select()
    3. End Sub


    Also nachdem die Form vollständig geladen ist, selektiert er die Textbox
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    Ohja, auf die Idee bin ich garnicht gekommen. Das geht ja auch.

    Aber gibt es nicht eine andere Lösung, in der die KeyEvents einfach funktionieren - egal was ausgewählt ist?
    Hier in der Anwendung wäre das ja wurscht.

    Aber in meiner Hauptanwendung ist es so, dass ich auf einer TabPage (nach Änderung mit MDIChild) mit Tasteneingabe immer die SucheTB beschreibe.
    Hier gibt es ein DGV, haufen Buttons, eine SuchenTB. Ich müsste ich dann jedem Control im Click Event TBSuche.Select() zuweisen.
    Ist ja bei nem Button kein Akt, nachdem der Code ausgeführt ist, die Textbox auszuwählen.
    Aber im DGV wäre das doof. Da kann ich dann z.B. nicht mit den Pfeiltasten durchscrollen, weil ja die Textbox ausgewählt sein muss.
    Außerdem gehen ja dann Dinge wie DGV Eintrag löschen mit "Del", oder kopieren mit "Strg + K" nur schwerlich.

    Neu

    Da bin ich überfragt - das müsste man sicher was entwickeln, was der Textbox immer wieder den Focus gibt. Seh' ich aber nicht als normalen Anwendungsfall an.
    In meiner Welt gibt's ne Tastenkombination für eine Suche oder der User muss eben in's Suchfeld reinklicken und dann was eintippen. Das ist ja im WIndows-Explorer etc.
    auch so gelöst.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Neu

    DerSmurf schrieb:

    Wenn ich ein DGV mit Daten habe, so ist standardmäßig die erste Zeile ausgewählt.
    Was ist daran unerwünscht?
    Ich finde es logisch, dass in jedem DGV ein Datensatz der fokussierte/selektierte ist.

    Etwa ein ein ParentChild-View oder ein Detail-View - da müsste man einigen Extra-Aufwand treiben, um konsistent darstellen zu wollen, dass nichts selektiert ist.