DataGridViewComboBoxColumn von DataTable mit DataSource

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    DataGridViewComboBoxColumn von DataTable mit DataSource

    Hallo Leute,

    ich brauch da ein wenig Hilfe:
    Ich habe eine DataTable erzeugt, welche ich nun in einem DataGridView anzeigen lasse. Dazu weiße ich meine DataTable einfach dem DataSource des DataGridView zu.
    Nun hat die DataTable aber auch eine Spalte, welche Werte in Listen (List(of String)) gespeichert haben. Nun möchte ich für jede dieser Liste eine Zelle haben, welche eine Combobox mit den Werten der Liste anzeigt.

    Kann man der DataTable mitgeben, wie die Spalten in einem DataGridView angezeigt werden? Also quasi, wenn eine Spalte der DataTable Listen enthält, dass dann das DataGrid automatisch DataGridViewComboBoxColumns für diese Spalten anzeigt?

    gegy schrieb:

    Nun hat die DataTable aber auch eine Spalte, welche Werte in Listen (List(of String)) gespeichert haben. Nun möchte ich für jede dieser Liste eine Zelle haben, welche eine Combobox mit den Werten der Liste anzeigt.
    Wat? Kannst da mal bitte den Erstellcode zeigen, also nur für diese betroffene Spalte? Weil: inhaltlich verwirrend. Sind in dieser Spalte nun Einträge vom Typ List(Of String) oder sind die Einträge was anderes, was nur irgendwo anders als List(Of String) gespeichert wird? Ich versteh den Abschnitt nicht …

    gegy schrieb:

    Kann man der DataTable mitgeben, wie die Spalten in einem DataGridView angezeigt werden?
    Ja, manuell den Spaltentyp festlegen. Aber nicht automatisch.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ok, ist vielleicht etwas verwirrend erklärt. Sorry.
    Also ich hab mal ein kleines Testbeispiel gebaut:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Dim data1 As New TestData With {.Name = "Spalte1", .Value = New List(Of String)({"Wert1", "Wert2"})}
    4. Dim data2 As New TestData With {.Name = "Spalte1", .Value = New List(Of String)({"Wert1", "Wert2"})}
    5. Dim dT As New DataTable
    6. Dim column1 As New DataColumn(data1.Name, data1.Name.GetType)
    7. dT.Columns.Add(column1)
    8. Dim dataObj1 As Object() = {data1.Value}
    9. dT.Rows.Add(dataObj1)
    10. Dim dataObj2 As Object() = {data2.Value}
    11. dT.Rows.Add(dataObj2)
    12. Me.DataGridView1.DataSource = dT
    13. End Sub
    14. Private Class TestData
    15. Property Name As String
    16. Property Value As Object
    17. End Class
    18. End Class


    In der DataTable dT hab ich eine Spalte (Spalte1). Die Tabelle hat zwei Zeilen. In den Zellen möchte ich nun daten nicht als Text-Zelle angezeigt bekommen, sondern als DataGridViewComboBoxCell.
    Deswegen die Frage, ob man der Spalte in der dT sagen kann, dass sie, wenn in einem DataGridView angezeigt, ihre Zellen als DataGridViewComboBoxCell darstellt.
    Du verwechselst DataColumn vom DGV mit einer DatatableColumn...
    Einer Datatable kann man pro Zeile und Spalte nur einen Wert zuordnen...
    Im DGV detto das gleiche - aber man kann im DGV die Column als DataGridViewComboboxColumn ausstatten, wo aus einer Liste von Werten ein Wert der DGV-Zelle zugewiesen werden kann...
    Ja du hast Recht. Ich hab inzwischen ein wenig experimentiert und es scheint so, als müsste ich mein DataGridView manuell aufbauen.
    Damit ich in der DataTable Zellen in den Zeilen mehr Werte zuweisen kann, hab ich die DataRow in ne eigene Klasse vererbt, wo ich ihr die realen Werte nochmals als Liste mitgebe.
    Mit dieser Basis werd ich mir nun mein Datagridview erstellen.

    Hab mein Beispiel inzwischen aufgebohrt, vielleicht hilft es ja mal jemand anderem:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Private Class TestData
    4. Property Name As String
    5. Property Value As Object
    6. End Class
    7. Private _grid As DataGridView
    8. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    9. _grid = Me.DataGridView1
    10. Dim data1 As New TestData With {.Name = "Spalte1", .Value = New BindingList(Of String)({"Wert1", "Wert2"})}
    11. Dim data2 As New TestData With {.Name = "Spalte2", .Value = New BindingList(Of String)({"Wert1", "Wert2"})}
    12. Dim data3 As New TestData With {.Name = "Spalte3", .Value = "Bernd"}
    13. Dim dataList As New List(Of TestData)
    14. dataList.Add(data1)
    15. dataList.Add(data2)
    16. dataList.Add(data3)
    17. Dim dT As New DataTable
    18. For Each item In dataList
    19. dT.Columns.Add(New DataColumn(item.Name, item.Value.GetType))
    20. Next
    21. Dim row As DataRow = dT.NewRow
    22. For Each item In dataList
    23. row.Item(item.Name) = item.Value
    24. Next
    25. dT.Rows.Add(row)
    26. _grid.AutoGenerateColumns = False
    27. _grid.VirtualMode = True
    28. _grid.AutoSize = True
    29. _grid.DataSource = dT
    30. _grid.AllowUserToAddRows = False
    31. For Each column As DataColumn In dT.Columns
    32. Select Case True
    33. Case column.DataType = GetType(BindingList(Of String))
    34. Dim data As BindingList(Of String) = dataList.FirstOrDefault(Function(i) i.Name = column.ColumnName).Value
    35. Dim col As New DataGridViewComboBoxColumn() With
    36. {.Name = column.ColumnName,
    37. .HeaderText = column.ColumnName,
    38. .DataPropertyName = "Value",
    39. .DataSource = data
    40. }
    41. col.DefaultCellStyle.NullValue = data(0)
    42. _grid.Columns.Add(col)
    43. Case Else
    44. Dim col As New DataGridViewTextBoxColumn() With {.Name = column.ColumnName, .DataPropertyName = column.ColumnName}
    45. _grid.Columns.Add(col)
    46. End Select
    47. Next
    48. End Sub
    49. End Class
    Ne, denke nicht. Spalten Anzahl und Typ der Spalten ist erst zur Laufzeit klar.
    Oder meinst du ich hänge meine dT an den Designer? Muss ich mir im Projekt ansehen. Ist halt so, dass ich die Instanzen der Datagrids auch erst zur Laufzeit generiere. Soll alles schön dynamisch bleiben.
    Richtig Dynamisch. Nein mein Datenmodel wird leider erst zur Laufzeit fixiert. Die Anzahl der Spalten und welchen Inhalt diese haben (Listen oder einzelner Wert) liegt nicht fest.
    Aber jetzt mal ne Grundsatzfrage: Kann es sein, dass ich die DataGridViewComboBoxColumn falsch interpretiere?
    Runtergebrochen auf eine Spalte, welche lauter Zeilen mit Comboboxen hat, welche aber unterschiedliche Werte in den Comboboxen haben, ist da die DataGridViewComboBoxColumn überhaupt das richtige?
    Muss ich mir da nicht eigentlich jede Zelle extra mit einer DataGridViewComboBoxCell erzeugen und diese befüllen?

    gegy schrieb:

    Runtergebrochen auf eine Spalte, welche lauter Zeilen mit Comboboxen hat, welche aber unterschiedliche Werte in den Comboboxen haben, ist da die DataGridViewComboBoxColumn überhaupt das richtige?
    Jo - geht net.
    Standard ist, dass alle Comboboxen einer ComboboxColumn dieselben Werte enthalten - nur jede Zelle kann einen anderen als 'den daraus ausgesuchten' Wert anzeigen.
    Ob man in jede Zelle sonstwie iwie eine ComboboxCell eingebastelt kriegt weiss ich auch nicht.

    Aber irgendwann wirst du dich wohl mal bequemen müssen, zu erzählen, was du eiglich vorhast.
    Nur so über iwelche Controls zu reden, wie du sie dir wünschst, und wie wir sie (anders) kennen - bringt glaub nicht viel.

    ErfinderDesRades schrieb:

    Aber irgendwann wirst du dich wohl mal bequemen müssen, zu erzählen, was du eiglich vorhast.


    ich hab die Frage extra "einfach" gehalten um vielleicht einen Lösungsvorschlag für einen kleinen Teil meines Projekts zu bekommen.
    Im Grund bekomme ich Daten aus einer Tabelle aus einem anderen System und muss mir aber die Daten in einer eigenen Tabelle selbst aufbereiten. Außerdem muss ich diese Tabellendaten auch noch um Informationen erweitern. Am Ende Soll die von mir aufbereitete Tabelle für den Anwender in nem Datagridview dargestellt werden. Der Anwender soll Zeilen löschen können und eben in den Comboboxen die Werte einstellen die er dort haben möchte. Am Schluss drückt er auf nen Knopf, die Tabelle wird exportiert und wo anders weiter verarbeitet.

    Ich hoffe das reicht als Erklärung, was ich vor habe?

    gegy schrieb:

    Der Anwender soll Zeilen löschen können und eben in den Comboboxen die Werte einstellen die er dort haben möchte.
    Ja - dafür sind ComboboxColumns vorgesehen - das meine ich mit

    ErfinderDesRades schrieb:

    alle Comboboxen einer ComboboxColumn dieselben Werte enthalten - nur jede Zelle kann einen anderen als 'den daraus ausgesuchten' Wert anzeigen.
    Also eine ComboboxColumn in einer Spalte für Lieferanten kann aus verschiedenen Lieferanten in jeder Zelle dieser Spalte einen auswählen.
    Und eine ComboboxColumn in einer Spalte für Gefahrenklasse kann aus verschiedenen Gefahrenklassen je Zelle der Spalte eine auswählen.
    Die Combos in der Lieferanten-Spalte können aber keinesfalls abwechslungsweise eine Gefahrenklasse zur Auswahl anbieten.

    Ansonsten reicht deine Erklärung nicht vorn und hinten.
    Also ich habe verstanden, dass du Tabellen bekommst, daraus andere Tabellen machen musst - unter Hinzuziehung weiterer Daten. Und die dann anzeigen präsentieren (d.h.: anzeigen und bearbeiten).
    Vermutlich wären Datagridviews mit ComboboxColumns geeignet zur Präsentation - wenn man es richtig anfängt.
    Ein Problem dabei ist, dass du der Ansicht bist, es könne dafür kein Datenmodell geben. Eine ComboColumn ist mit Sachverstand in einer für das Datenmodell geeigneten Art zu konfigurieren - ohne definiertes Datenmodell bin ich mal gespannt, wie das vor sich gehen soll.

    Gegenfrage: Reicht dir das jetzt als Antwort?

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

    Ich kenne dich schon ein wenig und weiß, dass deine Beiträge sehr schnippisch sind, aber damit kann ich umgehen. Da haben mir die Beiträge von VB1963 und VaporiZed mehr geholfen. ;)
    Ich bin nicht nur der Ansicht, dass es kein definiertes Datenmodel gibt, ich weiß es sogar... aber klar, damit du es auch weißt, müsstest du mein ganzes Projekt im Detail kennen und das kann ich hier aber nicht komplett aufrollen. Aber du hast richtig verstanden, dass ich Datagridviews zur Präsentation verwenden möchte. :)
    Ich hatte gehofft die Daten einfach an das Grid binden zu können, wie ich es sonst mit einem Datenmodel (Ansammlung von objekten) mache. Wie die Objekte dann dargestellt werden wäre kein Problem gewesen. Stichwort "CellPaint".
    Wenn das Model aber nicht klar ist, quasi wie die Ansammlung der Objekte nicht definiert ist, kann ich entweder auf dynamsiche Klassen ausweichen oder aber ich bastle mir mein Grid selbst zusammen und vernachlässige die Anbindung teilweise. So habe ich das nun auch gemacht. Ich erzeuge mir meine Zellen je nach Datentyp selbst. Klappt so auch.
    Nur ein Thema habe ich noch. Wenn ich eine neues DataGridview object erzeuge, dass dann "zusammenbastle" und der DataGridView auf dem Template zuweise (Einfache Form mit einem leeren DataGridView drauf), dann ist das Grid leer. Hole ich mir aber vorher das leere Grid vom Template und befülle es, dann sehe ich alles korrekt. Irgend eine Eigenschaft des DataGridViews muss ich wohl noch setzen.

    Oh und ergänzend noch: Ich habe oben schon geschrieben, dass ich da wohl was missverstanden habe mit der ComboColumn und der ComboCell. Ich benötige natürlich ComboCells, welche dann unterschiedliche Inhalte in deren Datasource haben.
    Ok ich hol mir einfach das Grid und befülle es, so geht es.

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

    gegy schrieb:

    Wenn ich eine neues DataGridview object erzeuge,... dann ist das Grid leer.


    vlt das hier:

    ObjectBrowser schrieb:

    Public Property AutoGenerateColumns As Boolean
    Member of System.Windows.Forms.DataGridView

    Summary:
    Gets or sets a value indicating whether columns are created automatically when the System.Windows.Forms.DataGridView.DataSource or System.Windows.Forms.DataGridView.DataMember properties are set.

    Returns:
    true if the columns should be created automatically; otherwise, false. The default is true.