Aus Klasse MainForm bearbeiten

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Aus Klasse MainForm bearbeiten

    Heyho.

    Ich habe hier eine Klasse "PlanetRegister", in der ich (bei meinem Versuchsspiel) alle erstellten Planeten registrieren kann und später auf diese auch zugreifen kann. Nun hat diese Klasse folgende Funktion:

    VB.NET-Quellcode

    1. 'TODO
    2. 'Den gelöschten Planeten auch aus der ListBox der MainForm löschen!
    3. Public Sub DeletePlanetByName(ByVal PlanetName As String)
    4. For i As Integer = 0 To liPlanets.Count - 1
    5. If liPlanets.Item(i).PlanetName = PlanetName Then
    6. liPlanets.RemoveAt(i)
    7. Exit For
    8. End If
    9. Next
    10. End Sub


    Damit wird ein Planet gelöscht. Jetzt muss dieser Planet aber auch aus der ListBox aus der Mainform verschwinden -wie stelle ich das am besten an?
    Ich hatte überlegt, mittels einer Schleifer alle registrierten Planeten durchzugehen und wenn einer nicht vorhanden ist, ihn später auch aus der ListBox zu entfernen. Das könnte aber später, bei mehreren Planeten, doch performancetechnisch nicht das gelbe vom Ei sein, oder?

    Spoiler anzeigen
    ​clsPlanetRegister

    VB.NET-Quellcode

    1. ​Public Class clsPlanetRegister
    2. Public liPlanets As List(Of clsPlanet)
    3. Public Sub New()
    4. liPlanets = New List(Of clsPlanet)
    5. End Sub
    6. Public Sub RegisterNewPlanet(ByVal Planet As clsPlanet)
    7. liPlanets.Add(Planet)
    8. End Sub
    9. Public Function GetPlanetByName(ByVal PlanetName As String) As clsPlanet
    10. Dim bPlanetFound As Boolean = False
    11. Dim planet As clsPlanet
    12. For Each planet In liPlanets
    13. If planet.PlanetName = PlanetName Then
    14. bPlanetFound = True
    15. Return planet
    16. Exit For
    17. End If
    18. Next
    19. If bPlanetFound = False Then
    20. Return Nothing
    21. End If
    22. End Function
    23. Public Function CheckForExistingPlanet(ByVal PlanetName As String) As Boolean
    24. End Function
    25. 'TODO
    26. 'Den gelöschten Planeten auch aus der ListBox der MainForm löschen!
    27. Public Sub DeletePlanetByName(ByVal PlanetName As String)
    28. For i As Integer = 0 To liPlanets.Count - 1
    29. If liPlanets.Item(i).PlanetName = PlanetName Then
    30. liPlanets.RemoveAt(i)
    31. Exit For
    32. End If
    33. Next
    34. End Sub
    35. End Class


    Spoiler anzeigen
    ​clsPlanet

    VB.NET-Quellcode

    1. ​Public Class clsPlanet
    2. Private _strPlanetName As String
    3. Private _structRessources As Ressources
    4. Private _MetalMines As Integer = 1
    5. Private _CrystalMines As Integer = 1
    6. Public Property PlanetName As String
    7. Get
    8. Return _strPlanetName
    9. End Get
    10. Set(value As String)
    11. _strPlanetName = value
    12. End Set
    13. End Property
    14. Public Property PlanetRessources As Ressources
    15. Get
    16. Return _structRessources
    17. End Get
    18. Set(value As Ressources)
    19. _structRessources = value
    20. End Set
    21. End Property
    22. Public Property MetalMines As Integer
    23. Get
    24. Return _MetalMines
    25. End Get
    26. Set(value As Integer)
    27. _MetalMines = value
    28. End Set
    29. End Property
    30. Public Property CrystalMines As Integer
    31. Get
    32. Return _CrystalMines
    33. End Get
    34. Set(value As Integer)
    35. _CrystalMines = value
    36. End Set
    37. End Property
    38. Structure Ressources
    39. Dim Metal As Double
    40. Dim Crystal As Double
    41. End Structure
    42. Public Sub New(ByVal PlanetName As String)
    43. Me.PlanetName = PlanetName
    44. Me.PlanetRessources = GenerateRessources()
    45. End Sub
    46. Private Function GenerateRessources() As Ressources
    47. Dim r As New Ressources
    48. r.Crystal = Math.Round(New Random().NextDouble, 2) + 1
    49. Threading.Thread.Sleep(50)
    50. r.Metal = Math.Round(New Random().NextDouble, 2) + 1
    51. Return r
    52. End Function
    53. End Class


    Ich weiß, die Klassen sind nicht die schönsten :P
    Wieso arbeitest du nicht mit einer List(of String) anstatt einer Listbox? ist die Listbox nötig für das Spiel oder nur um "Daten zu hinterlegen"?
    Auf der Suche nach Coding-Kursen auf Lence.at
    Naja, wenn die einzelnen Planeten Eigenschaften haben, dann reicht ein String aber ned aus :P

    Erstell dir eine Klasse namens clsPlanet oder so und dann machst du die ganzen Properties etc, das kann man dann auch alles schön serialisieren wenn du deinen Spielstand speicherbar machen willst und dann kannst du der Listbox anstatt strings einfach clsPlanet zuweisen.

    Und löschen kannst du dann ganz einfach indem du listbox.remove(planet1) machst.

    So in der Art stell ich mir das vor.
    Auf der Suche nach Coding-Kursen auf Lence.at
    In meiner "Register"-Klasse habe ich eine Funktion, mit der ich Anhand des "Namen" den Planeten aufindig machen kann:

    VB.NET-Quellcode

    1. ​Public Function GetPlanetByName(ByVal PlanetName As String) As clsPlanet
    2. Dim bPlanetFound As Boolean = False
    3. Dim planet As clsPlanet
    4. For Each planet In liPlanets
    5. If planet.PlanetName = PlanetName Then
    6. bPlanetFound = True
    7. Return planet
    8. Exit For
    9. End If
    10. Next
    11. If bPlanetFound = False Then
    12. Return Nothing
    13. End If
    14. End Function

    Diese Funktion wird aufgerufen, wenn ich auf der ListBox ein Item (dessen Text der Name des Planeten ist) anklicke. Daraufhin wird alles weitere verarbeitet anhand dieser Klasse, die mir zurückgegeben wird. Jetzt möchte ich aber auch einen Planeten löschen können, und da kommen wir zu meiner obigen Frage.
    Listboxen können praktischerweise nicht nur Strings auflisten sondern auch ganze Klassen. Mach doch da mal schlau :)
    Auf der Suche nach Coding-Kursen auf Lence.at
    @KingTimon

    Ich habe jetzt ein wenig recherchiert und komme auf Ergebnisse á la Serialisieren, XML etc. Ich denke, das ist nicht das was du meinst, geschweige denn, was ich benötige ?(

    @jvbsl
    Mit DataBinding habe ich mich schon auseinander gesetzt im Bezug auf DataGridViews und Datenbanken. Ich wüsste jetzt nicht, wie mir das hier weiterhelfen soll. Vielleicht ist es auch einfach nur zu spät für mich zum denken :P

    KingLM97 schrieb:

    Jetzt muss dieser Planet aber auch aus der ListBox aus der Mainform verschwinden
    Wieso gibt es diese Daten zwei mal?
    Ein mal muss genügen.
    Mach Dir eine geeignete Datenklasse, wo alle daten aufgesammelt sind, die kannst Du dann ganz easy pflegen und speichern.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    KingLM97 schrieb:

    Mit DataBinding habe ich mich schon auseinander gesetzt im Bezug auf DataGridViews und Datenbanken.
    Offensichtlich vollkommen unzureichend.
    Ist schon grundfalsch, Databinding im Zusammenhang mit Datenbanken zu sehen - an eine Datenbank kann man nix binden.
    Auch brauchst du hier keine Datenbank.

    Was du brauchst ist ein typisiertes Dataset - daran tut man binden. Ausserdem brauchst du überhaupt ein relationales Datenmodell, was du genau in dem typDataset anlegen müsstest.
    Ergibt 3 Lern-Voraussetzungen, bevor du ühaupt anfangen kannst, dein Projekt in Angriff zu nehmen:
    1. Was ist ein relationales Datenmodell, und was sind die Prinzipien, wie ein solches zu konzipieren ist?
    2. Wie setze ich das konkret im typDataset um?
    3. Wie konstruiere ich eine databinding-getriebene Oberfläche, die darauf aufbaut?
    Das alles im Zusammenhang kannste hier lernen: codeproject.com/Articles/1030969/Relational-Datamodel - es sind 3 aufbauende Artikel.
    Du wirst feststellen, Framework und VS bieten unglaublich mächtige Unterstützung für dieses Gesamtkonzept, und es löst ganz nebenbei auch dein Problem mit deiner Listbox - weil es deine ganze Denkweise ändert - weg von Controls, hin zu Daten - korrekt gedacht wäre nämlich:
    Ich lösche einen Planeten aus der Planeten-Tabelle.
    Mehr denken musst du nicht - ist eine Listbox an diese Planeten-Tabelle gebunden, so wird sie logisch diesen Planeten nicht mehr anzeigen - wie gesagt: da muss man nicht mehr drüber nachdenken.

    ErfinderDesRades schrieb:

    Offensichtlich vollkommen unzureichend.

    Nicht so, wie es im verlinkten Artikel beschrieben wird. Aber das ist eine andere Sache.

    Ich habe es versucht umzusetzen. (Anhang)
    Ginge das denn so? ?(

    Und: Wie kann ich dann eine XML-Datei laden, die dann mit diesem DataSet "arbeitet"?
    Bilder
    • sa.PNG

      16,02 kB, 1.296×732, 82 mal angesehen
    Dein Datenmodell bedeutet, jeder Planet hat mehrere Resourseses, und jedes Resources hat Metal und Crystal.
    Klingt wie Unfug,odr?
    Ist es nicht eher so, dass eine Resource Metal oder Crystal ist, aber nicht beides?
    Sind Metal und Crystal eiglich die einzigen Resourcen, dies gibt?
    Dann täte ja reichen, dem Planeten mit den Properties Metal und Crystal auszustatten, eine Extra-Tabelle Resources wäre üflüssig.

    Noch eigentümlicher mit Buildings - jeder Planet hat viele Buildingses, und ein Buildings hat Metalmine und Crystalmine.
    Ich kann mir ein Buildings mit Metal- und Crystal-Mine nicht recht vorstellen, in meiner Welt wäre denkbar, dass ein Building eine Metalmine oder Crystalmine ist - aber nicht, dass ein Buildings beides hat.
    Ich denke, du solltest die verlinkten 3 Artikel sehr sorgfältig lesen, und aufnehmen, was da steht.

    Da steht übrigens auch, wie man ein Dataset lädt oder als Datei speichert.
    Es steht dort nicht, wie du eine Datei laden kannst, die mit einem Dataset arbeitet, denn das gibts garnet. Dateien arbeiten nicht mit Datasetsen.
    Ich hätte mir die Klassen so in der Art gebaut:

    VB.NET-Quellcode

    1. Public Class Universe
    2. Public Property Planets as List(of Planet)
    3. End Class
    4. Public Class Planet
    5. Public Property Resources as List(of Resource)
    6. Public Property Buildings as list(of Building)
    7. End Class
    8. Public Class Resource
    9. 'diverse Methoden etc.
    10. End Class
    11. Public Class Crystal
    12. Inherits Resource
    13. End Class
    14. Public Class Building
    15. 'diverse Methoden, etc.
    16. End Class
    17. Public Class CrystalMine
    18. Inherits Building
    19. End Class


    So als kleine Inspiration.

    Und was dann ganz geschickt ist: du kannst die Klasse einfach serialisieren und damit speichern/laden. :)
    Auf der Suche nach Coding-Kursen auf Lence.at
    @ErfinderDesRades

    Ich habe nur Metal und Crystal genutzt (inkl deren Gebäude) um es zu verdeutlichen. Später soll es noch einige mehr geben.

    Und wieso klingt das wie Unfug?
    Jeder Planet hat die Ressourcen sowie die Gebäude. Das ist eigentlich richtig so, oder habe ich dich da falsch verstanden?

    ErfinderDesRades schrieb:

    Es steht dort nicht, wie du eine Datei laden kannst, die mit einem Dataset arbeitet, denn das gibts garnet. Dateien arbeiten nicht mit Datasetsen.

    Ja, da habe ich wohl unzureichend/falsch Gedacht. Wenn ich mir dann eine schöne XML-Datei erstelle, wie 'verbinde' ich diese mit dem DataSet, sodass ich dann später, wie im Beispielcode, mit For-Each, den Inhalt durchgehen kann? ?(
    @ErfinderDesRades was spricht gegen Klassen? -> schnell, einfach und mehr Möglichkeiten
    Auf der Suche nach Coding-Kursen auf Lence.at
    klassen können auch Datenmodelle bilden, und letztendlich ist auch das Datenmodell eines typDataset aus Klassen gebildet - allerdings aus für Datenverarbeitung besonders leistungsfähige Klassen.
    Jdfs. selbstgebastelte Klassen können nur hierarchische Datenmodelle abbilden, keine relationalen.
    Also wenn eine m:n - Relation auftritt, dann sind selbstgebastelte Klassen ein für allemal abgehängt.

    Lies auch du das verlinkte Tutorial, dann verstehst du, was eine m:n-Relation ist.

    KingTimon schrieb:

    was spricht gegen Klassen? -> schnell, einfach und mehr Möglichkeiten
    Was soll daran schnell sein?
    Was du skizziert hast ist doch noch lange noch nicht ansatzweise zu iwas brauchbar.
    Das musst du doch alles erst noch schritt für schritt entwickeln, fehler machen, debuggen, weiter entwickeln - du wirst sicher mindest. 3 Tage brauchen, ehe du die erste Anwendung hast, wo man Planeten und ihre Resourcen in einem DGV angugge kann, und zufügen, löschen, editieren, sortieren, filtern, abspeichern, laden.

    Ich bastel das in 20min, und es wird ein m:n-View, wo du Resourcen anlegen kannst und Planeten, sowie Zuordnungen, welcher Planet von welcher Resource wieviel verfügbar hat.
    Und andersrum kann mans auch präsentieren:
    Also nicht nur, welcher Planet von welcher Resource wieviel hat, sondern auch, welche Resource auf welchem Planeten zu finden ist, und wieviel.
    Weil das sind 2 unterschiedliche Sichtweisen derselben Sache, und das ist genau der Punkt, wo man mit dem Klassen-Ansatz in erhebliche Schwierigkeiten gerät, wo's nur noch mit Gewurstel hinzubiegen ist - was für ein relationales Modell ein banaler Standard-Fall ist.

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

    sry - bin ich nicht drauf eingegangen.
    Aber ich hab meiner Einlassung zu deim Datenmodell auch nichts hinzuzufügen.
    Es ist Unfug, wenn ein Resources Crystal und Metal hat, und später noch mehr.
    Crystal ist eine Resource, Metal ist auch eine Resource.

    Mein Tutorial zu Datenmodellierung gelesen?
    (Sieht mir nämlich nicht so aus, weil bei mir wären Entitäten singular benannt)

    Und wie du eine Xml-Datei mit einem Dataset verbindest ist mir auch schleierhaft. Man kann ein Dataset aus einer xml-Datei befüllen - das ergäbe Sinn. Und wird im Tut ja auch erläutert, und in den BeispielSources vorgeturnt.