Datagridview Combobox ValueMember Problem

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von KSE.

    Datagridview Combobox ValueMember Problem

    Hallo zusammen,

    ich habe in einem Dataset ein Datatable mit zwei Spalten erzeugt (ID u. Spaltennamen)

    Auf meiner Form befindet sich ein Datagridview in der sich eine Saplte IDSpaltennamen und eine DataGridViewComboBoxColumn Spaltennamen befindet.

    Die Datasource der Combobox ist mit der Bindingsource des Datatables meines Datasets verknüpft.

    DisplayMember=Spaltennamen

    ValueMember=ID

    DataPropertyname=IDSpaltennamen

    Das Datatable in meinem Dataset wird individuell über eine Liste befüllt.

    Das funktioniert auch prima. Im DGV wird in der Combobox der Inhalt richtig angezeigt.

    Wenn ich jetzt einen Wert auswähle wird aber nicht die ID an IDSpaltennamen übergeben??

    Folgende Fehlermeldung erscheint:

    Column 'ID' does not belong to table 'DTSpaltennamen'



    Hat das etwas mit dem individuellen befüllen meiner Datatable zu tun?? Weil ValueMember ist ja auf ID gestellt??
    Gruß von der KSE

    ks-entwicklung.de
    wenn dein Dataset nur eine Tabelle enthält, ergibt es keinen Sinn, eine ComboboxColumn ins DGV zu machen.

    die Combo einer ComboboxColumns ist dazu da, die ID eines übergeordneten Datensatzes aus einer übergeordneten DataTable auszuwählen, und als ForeignKey in den untergeordneten (in Bearbeitung befindlichen) Datensatz zu schreiben.

    Etwa in Phonebook gibt es die beiden Tabellen Person und Titel, und eine Combo wählt einen Titel aus und ordnet ihn der Person zu.
    Dann habe ich wohl Informationen vorenthalten. Denn genau so ist es wie du es schreibst.

    Die ID wird/soll in eine übergeordnete Tabelle (SpaltennamenID=ID) geschrieben. Das spezielle daran ist nur, dass ich die DatagridviewCombobox, die die ID weiter gibt je nachdem mit Einträgen gefüllt wird.

    Hier mal mein Code:

    VB.NET-Quellcode

    1. If TypeOf e.Control Is ComboBox Then
    2. '______________________________________________________________________________________
    3. Dim cmb = DirectCast(e.Control, ComboBox)
    4. If cmb.DisplayMember = "Spaltennamen" Then
    5. 'Filterspalten aus DB laden
    6. Me.Tbl_Filtergenerator_SpaltenTableAdapter.Fill(Filtergenerator.Tbl_Filtergenerator_Spalten)
    7. '________________________________________________________________________________________
    8. 'Bindingsource leeren
    9. For i As Integer = 0 To DTSpaltennamenDGVBindingSource.Count - 1
    10. DTSpaltennamenDGVBindingSource.RemoveCurrent()
    11. Next
    12. '____________________________________________________________________________________________
    13. 'Spalten in vorhandenem Filter einlesen
    14. If IsDBNull(Me.Tbl_Filtergenerator_FilterDataGridView.CurrentRow.Cells("Filterspalten").Value) Then Exit Sub
    15. Dim Filterspalten As String = Me.Tbl_Filtergenerator_FilterDataGridView.CurrentRow.Cells("Filterspalten").Value
    16. If Filterspalten = "" Then
    17. Exit Sub
    18. End If
    19. '____________________________________________________________________________________________
    20. '
    21. Dim dt As New DSFiltergenerator.DTSpaltennamenDGVDataTable
    22. For Each s As Data.DataRowView In Me.Tbl_Filtergenerator_SpaltenBindingSource.List
    23. Try
    24. For Each text As String In Filterspalten.Split(",")
    25. If text = (s.Row("Spaltennamen")).ToString Then
    26. Dim dr As DSFiltergenerator.DTSpaltennamenDGVRow = dt.NewDTSpaltennamenDGVRow
    27. dr.ID = (s.Row("ID"))
    28. dr.Spaltennamen = (s.Row("Spaltennamen"))
    29. dt.Rows.Add(dr)
    30. End If
    31. Next
    32. Catch ex As Exception
    33. Exit For
    34. End Try
    35. Next
    36. cmb.DataSource = dt
    37. cmb.ValueMember = dt.IDColumn.ColumnName
    38. cmb.DisplayMember = dt.SpaltennamenColumn.ColumnName
    39. End If
    Gruß von der KSE

    ks-entwicklung.de

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

    Ich merke, ich hätte vielleicht ersteinmal erklären sollen, was ich eigentlich vor habe.
    Für den ein oder anderen bestimmt ganz simpel.

    Ich lade aus einer DB ID und Spaltennamen (500Stück) in eine DatagridviewComboboxColumn.
    Die ID wird als ForeignKey in den untergeordneten (in Bearbeitung befindlichen) Datensatz geschrieben (Danke ErfinderdesRades :) )

    Ich habe ein String indem nur bestimmte Spaltennamen stehen und nicht alle 500 Stück.
    Ich möchte jetzt die Spalten aus dem String mit den Spalten aus der DB vergleichen und die überflüssigen raus schmeißen.

    Ich habe da jetzt schon einmal einen Ansatz der aber noch nicht richtig funktioniert:

    VB.NET-Quellcode

    1. For Each s As DataRowView In Tbl_Filtergenerator_SpaltenBindingSource.List 'Spaltennamen aus DB
    2. Dim uebereinstimmung As Boolean = False
    3. For Each text As String In Filterspalten.Split(",") 'Spaltennamen in String
    4. If text = s.Row("Spaltennamen") Then 'Spaltennamen String mit Spaltennamen DB vergleichen
    5. uebereinstimmung = True
    6. Exit For
    7. End If
    8. Next
    9. If uebereinstimmung = False Then 'keine Übereinstimmung, dann schmeiß row aus Spaltenname DB
    10. Tbl_Filtergenerator_SpaltenBindingSource.RemoveCurrent()
    11. End If
    12. Next
    13. End If
    Gruß von der KSE

    ks-entwicklung.de
    So, habe es jetzt hin bekommen. Ob es die beste Lösung ist bezweifle ich doch sehr, da es auch sehr lange dauert .....

    Hat jemand eine Idee, wie ich den Code optimieren kann?

    VB.NET-Quellcode

    1. For Each s As DataRowView In Tbl_Filtergenerator_SpaltenBindingSource.List
    2. Dim uebereinstimmung As Boolean = False
    3. For Each text As String In Filterspalten.Split(",")
    4. If text = s.Row("Spaltennamen") Then
    5. uebereinstimmung = True
    6. Exit For
    7. End If
    8. Next
    9. If uebereinstimmung = False Then
    10. Tbl_Filtergenerator_SpaltenBindingSource.Filter = "Spaltennamen='" & s.Row("Spaltennamen") & "'"
    11. If Tbl_Filtergenerator_SpaltenBindingSource.Count = 1 Then
    12. Tbl_Filtergenerator_SpaltenBindingSource.RemoveCurrent()
    13. Tbl_Filtergenerator_SpaltenBindingSource.Filter = ""
    14. End If
    15. End If
    16. Next
    17. End If
    Gruß von der KSE

    ks-entwicklung.de
    So, hab es nun umgestrickt.

    VB.NET-Quellcode

    1. Dim dt As DataTable
    2. dt = CType(Filtergenerator.Tbl_Filtergenerator_Spalten, DataTable)
    3. For Each rw As DataRow In dt.Rows
    4. Dim uebereinstimmung As Boolean = False
    5. For Each text As String In Filterspalten.Split(",")
    6. If text = rw.Item("Spaltennamen") Then
    7. uebereinstimmung = True
    8. Exit For
    9. End If
    10. Next
    11. If uebereinstimmung = False Then
    12. rw.Delete()
    13. End If
    14. Next


    Vom Prinzip her viel einfacher :-)!
    Was die Geschwindigkeit angeht hat sich aber leider nichts geändert!

    Hat jemand eine Idee zur Optimierung

    @ErfinderdesRades: Der Eintrag aus dem Datatable wird doch nur einmal überprüft. Wenn er nicht in "text" enthalten ist wird er gelöscht.
    Es gibt in "text", sowie in der Datatable keine doppelte Einträge?
    Gruß von der KSE

    ks-entwicklung.de
    Ach du sch.... das geht ja jetzt 100 mal schneller!!!


    VB.NET-Quellcode

    1. Dim dt As DataTable
    2. dt = Filtergenerator.Tbl_Filtergenerator_Spalten
    3. For Each rw As DataRow In dt.Rows
    4. Dim uebereinstimmung As Boolean = False
    5. For Each text As String In Filterspalten.Split(CChar(",")) 'CChar davor gesetzt
    6. If text = CStr(rw.Item("Spaltennamen")) Then 'CStr davor gesetzt
    7. uebereinstimmung = True
    8. Exit For
    9. End If
    10. Next
    11. If uebereinstimmung = False Then
    12. rw.Delete()
    13. End If
    14. Next


    In einer ruhigen Minute werde ich das ganze Projekt auf Option Strict ON stellen und zukünftige Projekte auch!!!!
    Danke ErfinderdesRades!!! :thumbsup:
    Gruß von der KSE

    ks-entwicklung.de
    probier auchma LinqToDataset:

    VB.NET-Quellcode

    1. Dim filterNames = New HashSet(Of String)(Filterspalten.Split(","c))
    2. Dim toDelete = From rw In Filtergenerator.Tbl_Filtergenerator_Spalten Where Not filterNames.contains(rw.Spaltennamen)
    3. For Each rw In toDelete.tolist
    4. rw.delete()
    5. Next