Dem Hannes zum OOP Durchblick verhelfen

  • VB.NET
  • .NET (FX) 4.0

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

    Dem Hannes zum OOP Durchblick verhelfen

    Wen es interessiert zur Einleitung Hintergrund lesen.

    Hintergrund:
    Spoiler anzeigen
    Liebe Community,nachdem ich nun meine erste Anwendung tatsächlich, auch in der Firma, praktisch nutzen kann, möchte ich diese bzgl. der Code Struktur, welche momentan vermutlich noch Event gesteuert gewachsen im Spaghetti-Code Muster vorliegt, optimieren. Ich habe in dieser ANwendung ein Dataset mit diversen Tabellen und Linq abfragen auf einem Form mit Tabpages. Mit Ausnahme des Login Systems (welches ich schon in einer separaten Klasse ausgelagert habe) ist alles im frmMain programmiert. Nun stellt sich mir eben die Frage was noch sinnvoll ausgegliedert werden kann. Daher bin ich so frei und eröffne diesen Thread indem ich mir erlaube euch Anfangs mit schmerzenden Grundlagen zu nerven um dann nach und nach den Code zu optimieren.Vllt. kann dann künftig der ein oder andere Neuling wie ich es einer bin was damit anfangen....


    1. Frage bezieht sich auf die absoluten Grundlagen der Klassen

    Meine erste KLasse zum testen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Kontakt
    2. Private myNachname, myVorname, myPlz, myOrt As String
    3. Private myErstellungsdatum As Date
    4. Sub New()
    5. myErstellungsdatum = Date.Now
    6. End Sub
    7. Public ReadOnly Property Erstellungsdatum As Date
    8. Get
    9. Return myErstellungsdatum
    10. End Get
    11. End Property
    12. Public Property Nachname() As String
    13. Get
    14. Return myNachname
    15. End Get
    16. Set(value As String)
    17. myNachname = value
    18. End Set
    19. End Property
    20. Public Property Vorname() As String
    21. Get
    22. Return myVorname
    23. End Get
    24. Set(value As String)
    25. myVorname = value
    26. End Set
    27. End Property
    28. Public Property Plz As String
    29. Get
    30. Return myPlz
    31. End Get
    32. Set(value As String)
    33. myPlz = value
    34. End Set
    35. End Property
    36. Public Property Ort As String
    37. Get
    38. Return myOrt
    39. End Get
    40. Set(value As String)
    41. myOrt = StringCutter(value, 10)
    42. End Set
    43. End Property
    44. Private Function StringCutter(ByVal text As String, ByVal MaxLength As Integer) As String
    45. Dim TextEdit As String
    46. If text.Length > MaxLength Then
    47. TextEdit = text.Substring(0, MaxLength - 3) + "..."
    48. Else
    49. TextEdit = text
    50. End If
    51. Return TextEdit
    52. End Function
    53. End Class[/code]
    54. [/spoiler]
    55. Nun die erste Frage: Wie kann ich in meinem kleinen Adressform mehrere instanzen dieser Klasse anlegen, möglichst indem ich jeder klasse ein "Adresskürzel" als Name zuweise?
    56. Bisher wird ja eine KLasse immer als
    57. [code]dim Adresse As new Kontakt [/code] instanziert.
    58. Was jedoch wenn ich mehrere Kontakte über kürzel instanzieren will und diese in einer Listbox einfügen will?
    59. Dieser Code bringt mir beim auffüllen der auf dem Form befindlichen Listbox eine Exception
    60. [spoiler]Ein Ausnahmefehler des Typs "System.NullReferenceException" ist in Klassentraining.exe aufgetreten.
    61. Zusätzliche Informationen: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.[/spoiler]
    62. [code]Public Class frmMain
    63. Dim adr(10000) As Kontakt
    64. Dim i As Integer = 0 'Counter
    65. Private Sub btnNewContact_Click(sender As Object, e As EventArgs) Handles btnNewContact.Click
    66. adr(i) = New Kontakt With {.Nachname = tbNachname.Text, .Ort = tbOrt.Text, .Plz = tbPlz.Text, .Vorname = TbVorname.Text}
    67. lblVorname.Text = adr(i).Vorname
    68. lblNachname.Text = adr(i).Nachname
    69. lblPlz.Text = adr(i).Plz
    70. lblOrt.Text = adr(i).Ort
    71. lblDate.Text = adr(i).Erstellungsdatum.ToString
    72. i += 1
    73. lbAdressen.Items.Add(adr(i).Nachname)
    74. lbliadr.Text = i.ToString
    75. End Sub
    76. End Class
    Gruß Hannes

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hans im glück“ ()

    Hab nicht alles gelesen, aber du erhöhst i und nutzt es danach noch.

    Grüße
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!

    Nikx schrieb:

    Hab nicht alles gelesen, aber du erhöhst i und nutzt es danach noch.

    Grüße
    ... das wars natürlich, doofer fehler!
    habs jetzt so gelöst:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class frmMain
    2. Dim adr() As Kontakt
    3. Dim i As Integer = 0 'Counter
    4. Dim AnzahlAdressen As Integer = 2
    5. Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    6. ReDim adr(AnzahlAdressen - 1)
    7. lblMöglicheAnzahlAdressen.Text = AnzahlAdressen.ToString
    8. End Sub
    9. Private Sub btnNewContact_Click(sender As Object, e As EventArgs) Handles btnNewContact.Click
    10. If adr.Length <= i Then
    11. ReDim Preserve adr(adr.Length + 4)
    12. lblMöglicheAnzahlAdressen.Text = adr.Length.ToString
    13. AnzahlAdressen = adr.Count
    14. End If
    15. adr(i) = New Kontakt With {.Kürzel = tbKürzel.Text,
    16. .Nachname = tbNachname.Text,
    17. .Ort = tbOrt.Text,
    18. .Plz = tbPlz.Text,
    19. .Vorname = TbVorname.Text }
    20. lbAdressen.Items.Add(i.ToString & " | " & adr(i).Kürzel & " | " & adr(i).Nachname)
    21. lbliadr.Text = i.ToString
    22. adressenanzeigen(i)
    23. i += 1
    24. End Sub
    25. Private Sub adressenanzeigen(ByVal index As Integer)
    26. lblVorname.Text = adr(index).Vorname
    27. lblNachname.Text = adr(index).Nachname
    28. lblPlz.Text = adr(index).Plz
    29. lblOrt.Text = adr(index).Ort
    30. lblDate.Text = adr(index).Erstellungsdatum.ToString
    31. End Sub
    32. Private Sub lbAdressen_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lbAdressen.SelectedIndexChanged
    33. adressenanzeigen(lbAdressen.SelectedIndex)
    34. End Sub
    35. End Class



    @VB1963 das stselle ich dann mal um und teste.
    Gruß Hannes

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hans im glück“ ()

    3 Anmerkungen dazu:
    1. aber solche Kontakt-Klassen sind doch insgesamt Müll, wenn du ein typisiertes Dataset hast.
      Da müsste es doch bereits eine Tabelle "Addresse" geben, der man derlei Daten zufügen kann.
      Und dann Listbox, und die verschiedenen Label dran binden, also in eier OOP/relational aufgezogenen Anwendung würde sich dein hier gezeigter Code auf eine oder zwei Zeilen reduzieren (und Code-Vereinfachung ist doch Ziel deiner Frage, oder?)
    2. Auch ist die Useability, also die Benutzbarkeit bei dir sehr fragwürdig:
      Weil ein Benutzer kann kaum erkennen, ob die Angaben, die da in verschiedenen Textboxen drinne stehen, ob das Angaben sind, was als nächstes zuzufügen ist, oder ob diese Daten soeben zugefügt wurden.
      Mal abgesehen von der Platzverschwendung, da mw. 5 Textboxen zur Eingabe rumfahren zu haben, und dann nochmal 5 Label, die dasselbe nochmal anzeigen, oder wie auch immer das bei dir organisiert ist.
      Ein besserer Workflow wäre, auf den Button-Klick würde sich ein Dialog öffnen, darin könnte man eingeben und übernehmen, oder auch canceln.
      Das würde das MainForm von vielen Controls befreien, und dem User wäre ganz klar, was er grade macht.
    3. Ist das ein typisiertes Dataset, was du hast, oder untypisierter (Müll)?
      Dementsprechend würde ich dir raten, das typsisierte nun auch als solches zu benutzen, oder halt erst nochmal neu anfangen damit.
    Hi Edr,

    nein die Anwendung auf die ich folgend in diesem Thread kommen will arbeitet bereits mit einem typ Dataset.

    Die Übung oben habe ich nur deshalb gemacht, da mir das Typ Dataset eben genau das abgenommen hat. Das das für ne Adressverwaltung unfug ist ist klar ;)
    ALleine einen Datensatz über eine Id in der Listbox löschen ist ja schon shit, sortieren kann ich nix bzw. nur aufwändig usw...

    Im beispiel oben ging es mir nur darum heraus zu bekommen zur laufzeit nicht eine statische instanz einer klasse, sondern flexibel mehrere instanzen zu erzeugen. hatte ich bisher nichts mit zu tun.
    Gruß Hannes

    hans im glück schrieb:

    Im beispiel oben ging es mir nur darum heraus zu bekommen zur laufzeit nicht eine statische instanz einer klasse, sondern flexibel mehrere instanzen zu erzeugen. hatte ich bisher nichts mit zu tun.


    Was hindert dich daran es zu machen?

    Im Prinzip ist

    VB.NET-Quellcode

    1. ​Dim i as Integer
    auch nichts anderes. Da kann man ja auch mehrere Variablen erzeugen. Bescheuertes Beispiel, ich weiß (wobei Integer selbst eine Klasse ist).
    so nun einmal zu eigentlichen konzeptionellen frage um mal zum thema zu kommen. prinzipiell könnte man sagen ich denke hier mal laut und warte auf euer feedback. also es gibt egtl. kein Problem oder fehler, sondern nur überlegungen den code zu optimieren.

    meine oben genannte anwendung sieht derzeit wie folgt aus:

    1 klasse für login, mit properties für erfolgreichen login und ein paar weiteren daten wie username, firma usw.
    wird dann per neuer instanz als modaler dialog im separaten form aufgerufen, die daten sind später entsprechend der properties verwendbar.

    hier war mir klar, dass das in eine sep. klasse kann, erstens für die nächste anwendung, zweitens haben die daten später mit der anwendung egtl. nichts mehr zu tun.

    1 string- extension für md5 hash erzeugung.


    1 frmMain: und hier ist der punkt an dem ich mich frage ob das so richtig ist, da ist ziemlich viel drin.
    auf dem form liegt ein tap control mit ca. 8 tap pages.
    der gesamte code im form main macht irgendwelche dinge mit einem typ dataset.

    egtl. ist das ganze ausschliesslich event basiert (ist das richtig was ich sage?), also es wird ein button gedrückt und dann passiert was.

    die frage ist, kann noch mehr ausgelagert werden in andere klassen? meiner meinung nach nicht.
    das frmMain ist ja deshalb ziemlich voll mit Methoden, da auch die Controls im frmMain liegen.

    die daten liegen ja ohnehin schon gekapselt im typ dataset, von daher denke ich egtl ist alles richtig oder?

    was ich mir noch überlegt habe, ist eine extension? zu erstellen mit der ich die cast´s auf die current binding source einfacher hin bekomme, das ist nämlich ein punkt der mitunter am häufigsten vorkommt.
    wobei ich mich auch hier frage ob der aufwand dann nicht größer ist?
    Gruß Hannes
    also wenn du mit "Klasse für login" einen Dialog meinst, dann ist das natürlich richtig, da ein Form zu basteln, wo User was eingeben muss, und das wird hinterher ausgewertet.
    Die LogIn-Daten müssen ja auch garnet in den Datenbestand.
    Kannste gugge Dialoge: Instanziierung von Forms und Aufruf von Dialogen - das kann man sehr elegant abhandeln.

    string-Extension ziehe ich in Zweifel, ob das wirklich eine Extension sein muss. Eine Methode sollte man imo nur dann als Extension anlegen, wenn man sie wirklich massenhaft verwendet. Grad die String-Klasse hat bereits irrsinnig viele Objekt-Methoden, und dieses Arsenal nu auch noch durch eine Extension zu erweitern - muss man halt abwägen.
    Vorausgesetzt, du verwendest den Begriff Extension in derselben Bedeutung wie ich - ansonsten reden wir von verschiedenen Dingen.

    frmMain: Jo, das ist die logische Entwicklung: Ein Form, was viel kann, enthält auch viel Code, und wird mit der Zeit immer unübersichtlicher.
    Ist zunächstmal unvermeidlich - wenn das Form was machen soll, muss der Code dazu auch ins Form rein.
    (Manch einer macht da schlimme Sünden, wenn ihm das Form zu voll wird, und er ohne Verstand in Module auslagert. Mit dem Ergebnis, dass dann aus iwelchen Modulen in iwelche Forms reingegrabscht wird. Sowas lieber lassen, bzw. da kann man immer Partiale Klassen anwenden.)
    Man hat allerdings auch ein erhebliches Arsenal an Möglichkeiten, wie man funktionale Teilbereiche doch in andere Klassen auslagern kann - was mir grad so einfällt:
    1. Partiale Klassen - ist eiglich eher eine "Pseudo-Strukturierung", bei der der Code ein und derselben Klasse schlicht in mehreren Dateien aufgeschrieben ist. Designer nutzen standard-mäßig das Partial-Feature für ihren generierten Code, aber natürlich kann man auch eigene partiale Klassen anlegen
    2. Bei Datenmanipulation gibts meist 2 plausible Orte, wo Code ansiedeln: entweder im Form, weil das Form das machen soll, oder in den DatenObjekten, weils mit den Datenobjekten gemacht wird. Letzteres nennt sich dann glaub auch Business-Logik.
    3. Manche Event-Behandlungen sind Standard-Reaktionen, und solch kann man in sog. "Behaviors" auslagern. Dann reduziert sich der Code im Form einzig auf die Aktivierung dieses Behaviors für dieses Control oder so.
    4. Databinding selbst ist ja ein gewaltiges Instrument um irrsinnige Mengen an Events und Daten-Verhalten zu konfigurieren
    5. Für abgrenzbare Benutzungs-Bereiche (zB Daten-Eingabe, Daten-Export, Browsing, Stammdaten) kann man auch UserControls anlegen, die sich drum kümmern. Die sind wie eigenständige Forms zu entwickeln, mit eigenem UserCode.
      Son Ucl kann man dann aus der Toolbox aufs Form packen, etwa mit ein ucl pro Tabpage fährt man oft sehr gut. Extrembeispiel gugge auf Async, Await und Task - jedes Sample ist ein Ucl, und das MainForm hat garkein UserCode mehr :P
    6. Wenig genutzte Benutzungs-Bereiche (Optionen, StammDaten) gehen natürlich gut auch in komplett eigene Dialoge.
      Aber auch eine Datenmaske ist natürlich ein eigener Dialog, nämlich der sich um genau eine "Unit-of-work" kümmert - solch isoliert man auch gerne, schon weil man solch auch canceln kann.
    7. Und natürlich immer drauf achten, nie gleich aussehenden Code zweimal zu schreiben. Solch kann man meist auslagern - muss man halt gucken - ein Modul, ein Extension-Modul, im selben Projekt oder in einer Helpers-Bibliothek, sowas. Ist ein Jonglieren und eine Frage von Muster-Erkennung, ob man so strukturieren kann, dass Einheiten entstehen, deren Innereien sehr viel miteinander interagieren (hohe Kohäsion), die aber nach aussen mit wenigstmöglichen Anknüpfpunkten interagieren müssen (Fachwort vergessen).
    Wenn wolle guggemol AdvancedPainting
    Da ist zu allen Punkten ausser 6) so allerlei drinne, unds Tut dazu spricht auch viel davon an.
    Die "DbExtensions" - im selben Download sind übrigens von Useability und Code-Aufteilung noch ein Stück advancter als das AdvancedPainting-Sample - die sind richtig nett vollgepflastert mit Behaviors, ucls, Business-Logik, Dialogen, Helper-Projekten, Databinding natürlich, und was ich nenne "advanced Databinding".

    Dieser Beitrag wurde bereits 15 mal editiert, zuletzt von „ErfinderDesRades“ ()

    zu meinem Ziel hin die Anwendung zu strukturieren habe ich nun ein Detailview in ein Form ausgelagert.
    Das Form ist hauptsächlich für eine Tabelle im Dataset zuständig, die jedoch künftig viel Einfluss auf andere Bereiche der Anwendung haben wird.

    Nun habe ich das Form Grenzwerte im Designer zusammen geklickst und folgenden Code im frmMain:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub GrenzwerteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GrenzwerteToolStripMenuItem.Click
    2. Dim Gw As New frmGrenzwerte
    3. Gw.DSGw = DS
    4. Gw.ShowDialog()
    5. End Sub
    6. 'Prozedur zur Prüfung ob Grenzwerte vorhanden sind / Image wird ein und ausgeschaltet
    7. Public Sub GrenzwertePrüfen()
    8. Dim Gw As New frmGrenzwerte
    9. Gw.DSGw = DS
    10. If Gw.GrenzwerteVorhanden Then
    11. PbKeineGrenzwerte.Hide()
    12. Else
    13. PbKeineGrenzwerte.Show()
    14. End If
    15. Gw.Dispose()
    16. End Sub


    Der COde des frmGrenzwerte sieht derzeit so aus:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class frmGrenzwerte
    2. Private _DSGw As DS 'DS ist hier das Typ Dataset des frmMain
    3. Private _GrenzwerteVorhanden As Boolean
    4. Private Sub Grenzwerte_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
    5. Main.GrenzwertePrüfen()
    6. End Sub
    7. Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
    8. Validate()
    9. TblGrenzwerteBindingSource.EndEdit()
    10. Me.Close()
    11. End Sub
    12. Public Property DSGw As DS
    13. Get
    14. End Get
    15. Set(value As DS)
    16. _DSGw = value
    17. TblGrenzwerteBindingSource.DataSource = _DSGw
    18. End Set
    19. End Property
    20. Public ReadOnly Property GrenzwerteVorhanden As Boolean
    21. Get
    22. If _DSGw.tblGrenzwerte.Rows.Count = 0 Then
    23. _GrenzwerteVorhanden = False
    24. Else
    25. _GrenzwerteVorhanden = True
    26. End If
    27. Return _GrenzwerteVorhanden
    28. End Get
    29. End Property
    30. Private Sub StandardGrenzwerteSetzen()
    31. If _DSGw.tblGrenzwerte.Rows.Count = 0 Then
    32. _DSGw.tblGrenzwerte.AddtblGrenzwerteRow(1, 1, 1, 1, 1, "Standard")
    33. End If
    34. End Sub
    35. Private Sub btnStandardwerte_Click(sender As Object, e As EventArgs) Handles btnStandardwerte.Click
    36. StandardGrenzwerteSetzen()
    37. End Sub
    38. End Class






    Soweit so gut (oder schlecht?)...

    Ich habe nun folgende Frage:

    Wenn ich in der Anwendung die Standardwerte in meinem instanzierten Dataset _DSGw setze (also nach dem Aufruf des frmGrenzwerte -> Standardwerte setzen) und danach das frmGrenzwerte schließe, kann ich beim speichern des original Datasets (also die Instanz die _DSGw zugewiesen wurde) im frmMain die Werte in der XML File sehen. Und das verstehe ich nicht, es soll zwar genau so sein, aber ich kann mir nicht erklären warum es so funktioniert.
    Die Daten stehen doch nicht im Hauptdataset DS, sondern in der Instanz _DSGw....
    Ich war mir egtl. sicher, dass ich einen Weg finden muss um die im _DSGw hinzugefügten Daten nach dem schließen der FrmGrenzwerte dem ursprünglichen DS hinzu zu fügen...

    Könnt Ihr mir erklären wie das zusammen hängt?



    Edit:

    Auch wenn ich den Standardkonstruktur ersetze gegen:

    VB.NET-Quellcode

    1. Public Sub New(ByVal Dataset As DS)
    2. ' Dieser Aufruf ist für den Designer erforderlich.
    3. InitializeComponent()
    4. _DSGw = Dataset
    5. TblGrenzwerteBindingSource.DataSource = _DSGw
    6. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    7. End Sub


    und dann instanzieren mit :

    VB.NET-Quellcode

    1. Private Sub GrenzwerteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GrenzwerteToolStripMenuItem.Click
    2. Dim _Gw As New frmGrenzwerte(DS)
    3. _Gw.ShowDialog()
    4. End Sub

    ändert sich das verhalten nicht, ich dachte erst es sei das selbe Schema wie mit Werte und Verweisypen (ByVal und ByRef) dann hätte es doch jedoch mit dem neuen Konstruktor nicht wieder ins Haupt Dataset übergeben werden dürfen oder?

    Gruß Hannes

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „hans im glück“ ()

    hans im glück schrieb:

    Wenn ich im Dialog werte in meinem Dataset _DSGw setze, und später im MainForm speichere, dann sind die Werte in der XML File. Und das verstehe ich nicht,
    Was gibts da nicht zu verstehen?
    Du übergibst das Main-Dataset dem Dialog, der Dialog verändert die Daten darin.
    Wenn du später, im MainForm das Main-Dataset dann speicherst - natürlich werden dann die geänderten Daten gespeichert.



    Übrigens sowas

    VB.NET-Quellcode

    1. Main.GrenzwertePrüfen()
    ist böse.
    Mach die Methode GrenzwertePrüfen() privat, dann kann dir son Quatsch garnet passieren. Dann bist du gezwungen, die Zuständigkeit zum GrenzwertePrüfen im MainForm zu belassen, wo sie ja hingehört.
    Das Mainform muss die Prüfung natürlich aufrufen, nachdem der Dialog mit DialogResult.Ok geschlossen wurde.

    gugge auch Dialoge: Instanziierung von Forms und Aufruf von Dialogen



    Übrigens, was du da tatsächlich als GrenzwertePrüfen() zeigst - das meinst du nicht ernst, oder?

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

    hans im glück schrieb:

    Wenn ich byval übergebe erhalte ich doch quasi eine Kopie und nicht das Orginal? Stehe ich auf'n Schlauch?
    Sieht so aus ;)

    Bei Referenztypen - und ein Dataset ist sowas - hantiert man mit Verweisen (Referenzen halt) auf das eigentliche Objekt.
    Also byval gibt tatsächlich nur eine Kopie des Verweises an die Methode, aber das Objekt, auf das durch diese Verweis(-Kopie) verwiesen wird, ist halt das eine und einzige Dataset deines MainForms.



    mit Grenzwerteprüfen() meine ich die Methode Grenzwerteprüfen() aus Snippet#1 in post#10 - was sonst?

    Prinzipiell mag eine Prüfung der per Dialog eingegebenen Daten sinnvoll sein, aber was du da gecodet hast, ist absurd - kannst du das nicht erkennen?
    ok super, das steht sogar explizit als beispiel in einem meiner bücher, hätte ich ja mal drauf kommen können :sleeping:
    man kann somit sagen, dass bei referenztypen byval und byref aufs gleiche raus kommen.

    wenn ich also mal eine tatsächliche copy eines datasets brauche muss ich das wohl mit

    VB.NET-Quellcode

    1. DS.copy()
    kopieren...



    ErfinderDesRades schrieb:


    mit Grenzwerteprüfen() meine ich die Methode Grenzwerteprüfen() aus Snippet#1 in post#10 - was sonst?

    Prinzipiell mag eine Prüfung der per Dialog eingegebenen Daten sinnvoll sein, aber was du da gecodet hast, ist absurd - kannst du das nicht erkennen?


    also ich könnte es insofern als absurd verstehen, als ich daten prüfe die im haupt ds ja schon vorliegen. könnte ich auch gleich an ort und stelle schauen ob die row/s vorhanden ist...
    von daher natürlich schwachsinn.
    da aber noch einige prüfungen hinzukommen sollten, bzw. die geschichte um rückgabe erweitert werden soll, dacht ich ich lasse alles im frmGrenzwerte liegen, dann wäre das dort logisch zusammen gefasst.oder meinste was anderes?

    ich hoffe das wars? ansonsten stehe ich wieder aufm schlauch =O



    Edit: Achso und noch eine Frage:

    Was ist nun der saubere Stil: Im Konstruktur das DS entgegen nehmen oder per Propertie mit Set?

    Und beim anlegen des Konstruktors war VS so nett und hat mir

    VB.NET-Quellcode

    1. ​ InitializeComponent()
    hingeschmissen...

    Brauch ich das?
    Gruß Hannes

    hans im glück schrieb:

    man kann somit sagen, dass bei referenztypen byval und byref aufs gleiche raus kommen.
    kann man nicht.
    Eine byref Argument kann (muss nicht) geändert werden, und das ändert die Variable beim Aufrufer! 8|
    Also wenn dein Dialog das Dataset byref bekommt, hat er die Möglichkeit, ein neues Dataset zu erstellen und zuzuweisen, und das würde vmtl. ein ziemliches Chaos im MainForm anrichten.
    Manchmal braucht man sowas, aber generell sollte man von byref einfach die Finger lassen.



    hmm - reden wir vom selben Code?

    post#10 schrieb:

    VB.NET-Quellcode

    1. Private Sub GrenzwerteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GrenzwerteToolStripMenuItem.Click
    2. Dim Gw As New frmGrenzwerte
    3. Gw.DSGw = DS
    4. Gw.ShowDialog()
    5. End Sub
    6. 'Prozedur zur Prüfung ob Grenzwerte vorhanden sind / Image wird ein und ausgeschaltet
    7. Public Sub GrenzwertePrüfen()
    8. Dim Gw As New frmGrenzwerte
    9. Gw.DSGw = DS
    10. If Gw.GrenzwerteVorhanden Then
    11. PbKeineGrenzwerte.Hide()
    12. Else
    13. PbKeineGrenzwerte.Show()
    14. End If
    15. Gw.Dispose()
    16. End Sub
    also in GrenzwerteToolStripMenuItem_Click() erstellst, betätigst und disposest du einen Dialog - das ist noch ganz logisch.
    Aber beim GrenzwertePrüfen() dann erstellst du nochmal ein Form derselben Klasse (war das Form als Dialog denn nicht gut?).
    Welches du aber überhaupt nicht anzeigst, sondern vom unsichtbaren Form rufstu du ieine Property ab, und setzst entsprechen eine Picbox.Visible oder nicht.

    mach doch einfach so:

    VB.NET-Quellcode

    1. Private Sub GrenzwerteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles GrenzwerteToolStripMenuItem.Click
    2. Dim Gw As New frmGrenzwerte
    3. Gw.DSGw = DS
    4. Gw.ShowDialog()
    5. PbKeineGrenzwerte.Visible = GrenzwertePrüfen
    6. Gw.Dispose()
    7. End Sub
    8. Private Function GrenzwertePrüfen() As Boolean
    9. Return DS.tblGrenzwerte.Rows.Count > 0
    10. End Function
    Das ist schon übertrieben kompliziert, halt im Vorgriff auf die Tatsache, dass du noch weitere Prüfungen durchführen willst.
    Und hast du gemerkt, dass die Function nun privat ist?
    (und der unsinnige Kommentar ist weg - das die Picbox entsprechend gesetzt wird steht ja bereits im Code.)

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    achso ok,
    das hängt damit zusammen, dass der button "GrenzwerteToolStripMenuItem" in den einstellungen liegt (die grenzwerte werden egtl. nur einmal vom user definiert).
    die überprüfung soll aber immer dann stattfinden wenn eine neue xml (Projekt) geladen wurde.
    es kann dann also sein, dass die instanz noch garnicht erstellt wurde da der user nicht in den einstellungen war.
    daher dachte ich mir gebe ich mit Gw.Dispose() einfach gleich nach verwendung die angelegte instanz wieder frei.

    alternativ könnte ich auch an geeigneter stelle die instanz erzeugen und dann für beide verwenden. man soll ja keinen gleichen code an mehreren stellen haben richtig?
    Gruß Hannes
    das verstehe ich jetzt nicht, ein in Einstellungen liegender Button, und irgendeine instanz, die's vlt. noch nicht gibt...

    Ich lese nur den Code, und wenn du die Werte prüfen willst, dann prüfe die Werte. Die Werte sind im Dataset, sie sind nicht in iwelchen Forms, die du zusätzlich erstellst um sie dann wieder zu disposen.