DataGridView per DataSource und BindingList aktuell halten

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

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von fabimaurice.

    DataGridView per DataSource und BindingList aktuell halten

    Hey ich bins mal wieder,

    ich habe das Problem dass ich nicht genau weiß wie ich mein DataGridView aktuell halten soll.
    Ich hatte eigentlich im Kopf, dass wenn eine Liste(in dem Fall halt nh BindingList) an das DataGridView gebunden ist und diese sich dann aktualisiert, indem z.B eine neue Lizenz hinzugefügt wird, sich das DataGridView auch aktualisiert.

    Bin alles mal Schritt für Schritt durchgegangen und die Liste aktualisiert sich auch, das neue Objekt taucht jedoch nicht im DataGridView auf.

    Falls jemand was dazu weiß freue ich mich über jede Antwort :) .

    Mfg Fabian
    Ich hab statt nem DGV ne ListBox. Klappt bei mir:

    VB.NET-Quellcode

    1. Private Liste As New ComponentModel.BindingList(Of String)
    2. Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. ListBox1.DataSource = Liste
    4. End Sub
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. Liste.Add("Test")
    7. End Sub

    Bei nem DGV werden ja immer die Objektdetails angezeigt. Und das wär bei nem String nur die Length. Bei (komplexen) Objekten kann man da natürlich mehr in nem DGV sehen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich habe mit den Infos von hier über dem Designer eine einfache Form zusammengeklimpert und ein DGV statt der im Beispiel verwendeten Listbox genommen und auch hier geht es ohne Probleme einen neuen "Datensatz" anzulegen anzeigen zu lassen.

    Mein Code soweit
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Private randomNumber As New Random()
    4. Private WithEvents listOfParts As BindingList(Of Part)
    5. Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
    6. InitializeListOfParts()
    7. DataGridView1.DataSource = listOfParts
    8. End Sub
    9. Private Sub InitializeListOfParts()
    10. ' Create the new BindingList of Part type.
    11. listOfParts = New BindingList(Of Part)
    12. ' Allow new parts to be added, but not removed once committed.
    13. listOfParts.AllowNew = True
    14. listOfParts.AllowRemove = False
    15. ' Raise ListChanged events when new parts are added.
    16. listOfParts.RaiseListChangedEvents = True
    17. ' Do not allow parts to be edited.
    18. listOfParts.AllowEdit = False
    19. ' Add a couple of parts to the list.
    20. listOfParts.Add(New Part("Widget", 1234))
    21. listOfParts.Add(New Part("Gadget", 5647))
    22. End Sub
    23. ' Create a new part from the text in the two text boxes.
    24. Private Sub listOfParts_AddingNew(ByVal sender As Object,
    25. ByVal e As AddingNewEventArgs) Handles listOfParts.AddingNew
    26. e.NewObject = New Part(TextBox1.Text, Integer.Parse(TextBox2.Text))
    27. End Sub
    28. Private Sub AddNewItem_Click(sender As Object, e As EventArgs) Handles AddNewItem.Click
    29. Dim newPart As Part = listOfParts.AddNew()
    30. If newPart.PartName.Contains(" ") Then
    31. MessageBox.Show("Part names cannot contain spaces.")
    32. listOfParts.CancelNew(listOfParts.IndexOf(newPart))
    33. Else
    34. TextBox2.Text = randomNumber.Next(9999).ToString()
    35. TextBox1.Text = "Enter part name"
    36. End If
    37. End Sub
    38. End Class


    Und noch die Part-Klasse dazu

    VB.NET-Quellcode

    1. ' A simple business object for example purposes.
    2. Public Class Part
    3. Private name As String
    4. Private number As Integer
    5. Public Sub New()
    6. End Sub
    7. Public Sub New(ByVal nameForPart As String,
    8. ByVal numberForPart As Integer)
    9. PartName = nameForPart
    10. PartNumber = numberForPart
    11. End Sub
    12. Public Property PartName() As String
    13. Get
    14. Return name
    15. End Get
    16. Set(ByVal value As String)
    17. name = value
    18. End Set
    19. End Property
    20. Public Property PartNumber() As Integer
    21. Get
    22. Return number
    23. End Get
    24. Set(ByVal value As Integer)
    25. number = value
    26. End Set
    27. End Property
    28. End Class

    Ich gehe mal, da kein Code gezeigt wird, vom Standard-Anfängerfehler aus, dass versucht wird, einfache Elemente oder eine Structure anzubinden.
    Das klappt leider nicht. Es funktioniert nur mit Properties. Bitte halte dich an das Beispiel von Dksksm. Wenn es doch noch zusätzlich anders funktionieren sollte, dann bin ich ganz Ohr ...
    An manchen Tagen gibt es zu allem Überfluss auch noch Ärger!

    Rainman schrieb:

    Ich gehe mal, da kein Code gezeigt wird, vom Standard-Anfängerfehler aus, dass versucht wird, einfache Elemente oder eine Structure anzubinden.
    Das klappt leider nicht. Es funktioniert nur mit Properties. Bitte halte dich an das Beispiel von Dksksm. Wenn es doch noch zusätzlich anders funktionieren sollte, dann bin ich ganz Ohr ...


    Klar bin ich Anfänger aber das ich keinen Code hinzugefügt habe liegt daran das ich dachte, dass es einfach ein Verständnis Problem ist und nichts mit dem Code zutun hat :). Aber damit Leute wie du dann nicht so (ist nur ein Gefühl und falls es nicht so ist sage ich gerade nichts^^) herablassend ihren Senf dazu geben ohne zu helfen, Pack ich mal rein was ich so an Code dafür benutze ^^. <Edit: Habe mir dein Kommentar nochmal durchgelesen und binn zu dem Schluss gekommen das er nicht unbedingt herablassend war jedoch einfach Unnötig und unbrauchbar da alles bereits vorher so erwähnt wurde und du nur im Prinzip nur Dksksm abgenickt hast und einige nutzlose Sachen beschrieben hast. Bei deinem Kommentar hätte vermutlich ein einfaches und höfliches "Könntest du noch den Code dazu stellen weil normalerweise sollte es funktionieren" gereicht.

    Code:

    VB.NET-Quellcode

    1. Public Function ReadSoftware() As BindingList(Of ClsSoftware)
    2. Dim Softwarelist As New BindingList(Of ClsSoftware)
    3. Cmd.Connection = Con
    4. Try
    5. Con.Open()
    6. Cmd.CommandText = "SELECT * FROM Softwares"
    7. reader = Cmd.ExecuteReader
    8. Do While reader.Read
    9. Softwarelist.Add(New ClsSoftware(CInt(reader("id")),
    10. CType(reader("software"), String),
    11. CType(reader("comments"), String),
    12. CType(reader("version"), String)))
    13. Loop
    14. reader.Close()
    15. Con.Close()
    16. Catch ex As Exception
    17. MessageBox.Show(ex.Message)
    18. End Try
    19. Return Softwarelist
    20. End Function

    Hier fülle ich zuerstmal die Bindinglist per reader(ja ich weiß es gibt bessere Lösungen aber so sieht nunmal meine Aufgabenstellung aus). Die Klasse also ClsSoftware sieht wie folgt aus:

    VB.NET-Quellcode

    1. Public Sub New(id As Integer, Optional Software As String = "", Optional comments As String = "", Optional version As String = "")
    2. Me.id = id
    3. Me.software = Software
    4. Me.comments = comments
    5. Me.version = version
    6. End Sub
    7. Public Property id As Integer
    8. Public Property software As String
    9. Public Property comments As String
    10. Public Property version As String
    11. End Class


    Dann kommen wir doch mal dazu wie ich das DataGridView befülle:

    VB.NET-Quellcode

    1. softwarelist = ReadSoftware()
    2. DgvSoftware.DataSource = softwarelist


    So weit so gut sind bestimmt einige Fehler drin, daher als kleine Anmerkung: Verbessert mich bitte nach Lust und Laune, damit ichs danach besser weiß.

    Jetzt öffne ich per Showdialog eine Form, über die ich z.B eine Software hinzufügen möchte. Wenn ich den "Add" Button betätige setze ich am Ende davon das Dialogresult auf Dialogresult.Ok und rufe auf der Main Form dann hiermit das Dialogresult ab.

    VB.NET-Quellcode

    1. Dim frm As New FrmSoftware(FrmSoftware.FrmMode.Add, DgvSoftware.CurrentRow.Cells(0).Value)
    2. If frm.ShowDialog = DialogResult.OK Then
    3. softwarelist = ReadSoftware()
    4. End If


    Über die If Abfrage fügt er die neue Software auch der Liste hinzu. Diese erscheint bloß nicht im DataGridView.

    Also falls jetzt jemand etwas genaueres weiß wo mein Fehler liegt würde ich mich sehr freuen.
    Die BindingList meldet sich, wenn ihr Inhalt geändert wird, nicht, wenn sie selbst geändert/ersetzt wird.

    Würdest Du theoretisch schreiben:

    VB.NET-Quellcode

    1. Dim Softwarelist As New BindingList(Of ClsSoftware)
    2. '…
    3. DgvSoftware.DataSource = Softwarelist
    4. '…
    5. Softwarelist.Add(…)
    ginge es.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Habs mir gerade auch nochmal so aufgefallen durch euch :D. Macht ja im Prinzip auch Sinn. Wenn ich es richtig verstanden habe instanziert meine funktion ReadSoftware jedess mal eine Neue Liste wodurch die Relation zum DataGridView verloren geht womit ich zwar einen neuen Wert in der Liste habe der aber durch die fehlende Relation zum DGV nicht übernommen wird.

    Dann danke an @ErfinderDesRades @Dksksm & @VaporiZed ihr wart mir eine riesen Hilfe auch was das verständnis angeht DANKE! :) Habe es dadurch jetzt auch zum laufen gebracht.
    @ErfinderDesRades
    Tut mir leid das ich solange nicht geantwortet habe war an einem anderen Projekt & dachte das Thema wäre abgeschlossen.
    Also soll ich quasi im Programm die Datensätze zur Liste hinzufügen diese aber nicht auser der Datenbank holen? So wären es zumindest sehr viel weniger Datenbankzugriffe die das ganze echt recht unperformant machen. Ich werde das jetzt mal so ausprobieren weil es zumindest mal nicht meiner Aufgabenstellung wiederspricht.