Fragen zum Objekt-Binding

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von sronny.

    Fragen zum Objekt-Binding

    Ich bin ja fleißig am VB-Lernen. Nun habe ich schon mal eine kleine Adressverwaltung mittels typisierten Dataset und den Videos von @ErfinderDesRades gebastelt. Sieht auch schon ganz hübsch aus. Bin aber mit meinem geplanten Projekt noch lange nicht fertig. Eigentlich soll man ja Frontend und Backend trennen. Also beschäftige ich mich gerade mit Objektbinding.

    Ich habe mir da erstmal kleine Klassen gebastelt, welche ich auch schon mal mit nem Datagridview, Textboxen etc. gebunden habe. Funktioniert schon mal.
    Nun wollte ich aber Sub-Klassen an eine Combobox bzw. mit ins Datagridview einbinden.

    Ich habe da auch mal einen kleinen Code vorbereitet(ist aber nur ein Auszug als Beispiel):

    VB.NET-Quellcode

    1. public Class clsPerson
    2. Private _Name1 As String
    3. Public Property Name1() As String
    4. Get
    5. Return _Name1
    6. End Get
    7. Set(ByVal value As String)
    8. _Name1 = value
    9. End Set
    10. End Property
    11. Private _AdresseItem As clsAdresse
    12. Public Property AdresseItem(ByVal i As Integer) As clsAdresse
    13. Get
    14. Return lstAdresse.Item(i)
    15. End Get
    16. Set(ByVal value As clsAdresse)
    17. _AdresseItem = value
    18. End Set
    19. End Property
    20. Private _lstAdresse As clsAdresseliste = New clsAdresseliste
    21. Public Property lstAdresse() As clsAdresseliste
    22. Get
    23. Return _lstAdresse
    24. End Get
    25. Set(ByVal value As clsAdresseliste)
    26. _lstAdresse = value
    27. End Set
    28. End Property
    29. end class
    30. public Class clsPersonListe
    31. Inherits System.ComponentModel.BindingList(Of clsPerson)
    32. end class
    33. public class clsAdresse
    34. Private _Strasse As String
    35. Public Property Strasse() As String
    36. Get
    37. Return _Strasse
    38. End Get
    39. Set(ByVal value As String)
    40. SetProperty(_Strasse, value, "Strasse")
    41. End Set
    42. End Property
    43. public sub new()
    44. end sub
    45. public sub new(byval dStrasse as string)
    46. Strasse = dStrasse
    47. end Sub
    48. end class
    49. public Class clsPersonListe
    50. Inherits System.ComponentModel.BindingList(Of clsPerson)
    51. end class


    Achja, ​INotifyPropertyChanged ist implementiert...

    Warum eine Adressenliste? Weil ich jede Person mehrere Adressen haben kann...

    Ich kann die erstellten Objekte auch alle brav füllen und entsprechend auch abrufen.

    Also mit ​oPerson.Name1 kann ich die Property anzeigen lassen. Ich kann auch mit ​operson.lstAdresse.Item(x).Strasse die Strasse aufrufen - oder direkt
    mit ​pers.AdresseItem(x).Strasse).

    Was aber nicht funktioniert ist, dass ich in nem DatagridView die Strasse angezeigt bekomme.
    Also ich habe erst eine BindingList mit Personen und deren Adressen gefüllt (lstPersonen) und dann diese an eine Bindingsource gebunden. Dieses an ein DGV gebunden funktioniert auch - Personen werden angezeigt.

    Nun wollte ich eine Bindingsource an die lstAdresse der einzelnen Person binden um diese dann in dem DGV die Adresse als Spalte angezeigt zu bekommen - sei es einzeln - also Spalte für Strasse, PLZ, Ort oder meinetwegen auch als einzige Spalte mit Strasse PLZ Ort. Das aber funktionert nicht. Bei ner Datenbank oder dem Dataset klappt es ja, indem man eine Tabelle PersonAdresse bastelt und diese ans DGV bindet, Adressbindingsource an die Combobox dann die ID als Wertmember auswählt und das DGV sucht sich was es braucht. Hier funktioniert das nicht so einfach.

    Wie bekommt man sowas hin?

    Auf die Sache mit dem Objektbinding bin ich durch den Beitrag von @ErfinderDesRades Singleton, Serialisierung (Json, Xml) und Databinding ohne Dataset gestossen. Leider habe ich das Problem, dass ich dessen Solutions nicht bei mir in VS 2015 Com. zum laufen bekomme. Da bekomme ich leider ständig nur Fehlermeldungen - zum einen muss einiges migriert werden und dann im Anschluss funktioniert nix mehr...Daher konnte ich das auch nicht weiter anschauen...

    sronny schrieb:

    Da bekomme ich leider ständig nur Fehlermeldungen
    Welche?
    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!
    witzigerweise hats jetzt grad mal funktioniert. Das fängt an von kann nicht die einzelnen Sachen laden oder findet diese nicht, kann nicht öffnen etc. Jetzt eben hat es funktioniert, kann also grade nichts genaues sagen.
    Habs jetzt mal beim Solution-Explorer versucht da kommen diese Fehlermeldungen:
    Spoiler anzeigen

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand Fehler BC2017 Bibliothek "d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\bin\Debug\Helpers.dll" wurde nicht gefunden SolutionExplorer d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\SolutionExplorer\vbc 1 Aktiv Fehler BC30183 Das Schlüsselwort ist kein gültiger Bezeichner. Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 401 Aktiv Fehler BC30183 Das Schlüsselwort ist kein gültiger Bezeichner. Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 407 Aktiv Warnung BC42353 Die Funktion "IndexOfKey" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 34 Aktiv Warnung BC42353 Die Funktion "AddIfNew" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 41 Aktiv Warnung BC42353 Die Funktion "CountChars" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\StringX.vb 188 Aktiv Warnung BC42353 Die Funktion "CountSubStrings" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\StringX.vb 200 Aktiv Warnung BC42353 Die Funktion "IndexOf" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\Collection\CollectionX.vb 210 Aktiv Warnung BC42353 Die Funktion "IndexOf" gibt nicht für alle Codepfade einen Wert zurück. Fehlt eine Return-Anweisung? Helpers d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\Collection\CollectionX.vb 219 Aktiv


    naja. Zu meinem Problem, habe es jetzt schon mal soweit geschafft, dass ich zu der Personenlist-Bindingsource eine weitere mit

    bsAdressenlist.datasource = bsPersonlist bsAdressenlist.datamember = lstAdressen

    damit konnte ich in der Combobox die Adresse auswählen, aber die verschwand dann auch gleich wieder, nachdem ich etwas anderes ausgewählt habe. Wie schaffe ich es nun, dass automatisch immer der erste Eintrag ausgewählt wird und dann auch bleibt?

    PS: Die Combobox:

    ​ .datapropertyname = "" .datasource = bsAdressenlist .Displaymember = Strasse .ValueMember = ""
    na ich meinte die Combobox des DGV:



    und so schauts aus, wenn ich die Form öffne.ist jetzt ne einfache Testform. Überall Adressen leer, und falls jemand eine hat, kann ich die auswählen. Klicke ich eine andere Person an, wird die Adresse wieder ausgeblendet...




    In einem extra DGV wird brav immer abhängig der Person die Adressen angezeigt:



    Die lstPerson ist eine globale Variable der Form. In einer lokalen Variable "Person" wird eine Person angelegt und diese dann in die lstPerson geaddet.
    Somit verstehe ich, dass die Personen alle angezeigt werden können, da die List ja immer verfügbar ist, während die Bindingsource der Adresse (ListChange nach Personwechsel) sich ja immer ändert und damit die Adressen wieder weg sind. Ist mir soweit einleuchtend.

    Aber wie muss ich die Bindungen umstellen - oder welche Propertys in welchen Klassen wo anpassen, damit die Adressen immer auswählbar sind? In den Einstellungen der DGV-Combobox ist bspw. die Property lstAdresse von Person nicht auswählbar - wird nicht angezeigt - nur unter Datenquellen. Kann ich also auch nicht auswählen. Da ich da auch gerade anfange mich damit zu beschäftigen habe ich auch noch nichts richtiges gefunden, weil ich auch nicht so richtig weiß, nach was ich suchen muss...
    Ich weisses grad auch nicht - ist länger her. Sieh doch einfach zu, das Tut ans Laufen zu bringen.

    sronny schrieb:

    Bibliothek "d:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\bin\Debug\Helpers.dll" wurde nicht gefunden
    deutet daraufhin, dass du das entpackte Dateisystem iwie zerpflückt hast, oder die Solution nicht mit einer .Sln-Datei öffnest, sondern mit einer .vbproj.
    Oder sowas.
    Oder du hast nicht kompiliert - jdfs. iwas ungeschicktes, und wär eh gut, mit mehreren Projekten in einer Solution arbeiten zu können zu lernen.

    Ah - ich glaub, das geht garnet, was du vorhast. Du willst einen "Joining-View" bauen, und das ist mit einem OOP-Datenmodell nicht machbar.
    Tatsächlich willst du was noch komplizierteres bauen, etwas was aussieht wie ein Joining-View, aber die Auswahl aus den ChildRows des aktuellen Datensatzes hernimmt. Wenn ich dich recht verstanden habe. Das geht aber allenfalls mit Tricks.
    Mach dich doch erst mit den Standard-Views vertraut - hast du schon einen Parent-Child gebastelt? Dafür ist ein OOP-Datenmodell gut geeignet.

    Kannst dir auch das 4-View-Tut angucken, aber wenn du die BeispielCodes nicht ans laufen kriegst ist natürlich mühsam.
    vier Views-Videos

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

    Sodela, gestern war Antworten nicht mehr möglich, weil Valentinstag :rolleyes:

    Jep, sollte nen JoiningView werden. ParentChildView habe ich hinbekommen. Die Videos kenne ich schon. Damit habe ich mit dem ganzen mal angefangen. Das ganze habe ich auch schon hübsch gebastelt bekommen. Wollte halt jetzt mit weitergehen. Naja.

    Zum Solutinexplorer: Habe die Datei vom Dez. 2013, diese entpackt und die .sln geöffnet. Darin sind die beiden Projekte Helpers und SolutionExplorer. Bei Starten kommen diese Fehlermeldung:

    Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
    Fehler BC30183 Das Schlüsselwort ist kein gültiger Bezeichner. Helpers D:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 401 Aktiv

    Fehler BC30183 Das Schlüsselwort ist kein gültiger Bezeichner. Helpers D:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\0System\SmallClasses.vb 407 Aktiv

    Fehler BC2017 Bibliothek "D:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\Helpers\bin\Debug\Helpers.dll" wurde nicht gefunden SolutionExplorer D:\Eigene Dateien\Eigene Dokumente\Ebook\SolutionExplorer2010Src\SolutionExplorer\vbc 1 Aktiv

    Und diese erhalte ich auch, wenn ich versuche nur das Projekt Helpers zu kompilieren(Erstellen/Helpers erstellen, bzw
    Helpers neu erstellen). Die ersten zwei Fehlermeldungen sind halt aus dem Helpers-Projekt und beziehen sich auf diese beiden Propertys:

    VB.NET-Quellcode

    1. Default Public ReadOnly Property NameOf(ByVal Val As Object) As String
    2. Get
    3. Return EnumValue.GetName(Of T)(Val)
    4. End Get
    5. End Property
    6. Default Public ReadOnly Property NameOf(ByVal Val As T) As String
    7. Get
    8. Return EnumValue.GetName(Of T)(DirectCast(CObj(Val), Integer))
    9. End Get
    10. End Property


    Der beschwert sich, dass ​NameOf kein gültiger Bezeichner ist...

    Hier mal die die Solution, welche ich verwende:
    SolutionExplorer2010Src.zip
    @sronny
    Bau' mal so um:

    VB.NET-Quellcode

    1. Default Public ReadOnly Property [NameOf](ByVal Val As Object) As String
    2. Get
    3. Return EnumValue.GetName(Of T)(Val)
    4. End Get
    5. End Property
    6. Default Public ReadOnly Property [NameOf](ByVal Val As T) As String
    7. Get
    8. Return EnumValue.GetName(Of T)(DirectCast(CObj(Val), Integer))
    9. End Get
    10. End Property

    us4711 schrieb:

    @sronny
    Bau' mal so um:


    Ich danke dir - das hat funktioniert. Programm hat brav kompiliert und ist gestartet. Kam mir halt bissl doof vor zu fragen, weil der SE ja nun schon eine ganze Weile angeboten wird und sich noch niemand beschwert hat. Da sucht man zwangsläufig den Fehler bei sich...

    Kam jetzt erst mal nicht an den Computer und konnte daher nicht gleich antworten...