Datagridview ComboBox

  • VB.NET

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

    Datagridview ComboBox

    Hallo Leute,
    habe mich heute endlich den Sprung vom langjährigen passiv Leser in Nutzer gewagt.
    Habe auch direkt ein Problem welches ich durch bloße Suche nicht gelöst bekomme.

    Und zwar lese ich eine sqlite Tabelle aus und binde sie direkt an ein DataGridView. Die Tabelle besteht aus 2 Spalten einmal "artno" und "pruefplan" die als Text in der Datenbank hinterlegt sind. Jetzt möchte ich, dass bei der Spalte pruefplan eine ComboBox erzeugt wird, deren Items aus einer anderen Datenquelle (Array aus Directories) gespeist werden.
    Als Endergebnis möchte ich also im Feld "pruefplan" aus einer Liste an festgelegten sowie vorab bekannten Möglichkeiten wählen.

    Das ganze soll konsistent sein, so dass ich die editierte Tabelle zurück in die Datenbank schreiben kann.

    Mein bisheriger Ansatz sieht wie folgt aus (Columns habe ich im Desinger definiert)

    VB.NET-Quellcode

    1. Dim databaseConnection As New SQLiteConnection("Data Source=system.db;")
    2. Dim userdatabaseAdapter As New SQLiteDataAdapter(New SQLiteCommand("SELECT * FROM `users`", databaseConnection))
    3. Dim artikelDatabaseAdapter As New SQLiteDataAdapter(New SQLiteCommand("SELECT * FROM `artikel`", databaseConnection))
    4. Dim artikelDataTable As New DataTable()
    5. Private Sub updateArtikelList()
    6. Dim bs As New BindingSource
    7. artikelDataTable.Clear()
    8. artikelDatabaseAdapter.Fill(artikelDataTable)
    9. dgvArtikel.AutoGenerateColumns = False
    10. dgvArtikel.DataSource = artikelDataTable
    11. dgvArtikel.Columns(0).DataPropertyName = "artikelno"
    12. dgvArtikel.Columns(1).DataPropertyName = "pruefplan"
    13. End Sub

    Logischerweise funktioniert das nicht, da ich keinen Text in eine ComboBox ohne weiteres übergeben kann.

    Ich habe bisher leider nur Lösungen gefunden die eine DataTable als Items einer ComboBox übergibt.

    jdoerr schrieb:

    Ich habe bisher leider nur Lösungen gefunden die eine DataTable als Items einer ComboBox übergibt.
    Jo, das ist gängiger, wohl aus gutem Grund.
    Aber prinzipiell geht das ebenso auch mit einem

    jdoerr schrieb:

    Array aus Directories
    - was immer das eigentlich sein mag.
    Welchen Datentyp hat dein "Array aus Directories" denn?
    Hab ich warscheinlich ein wenig ungünstig ausgedrückt. Ich lese ein Verzeichnis ein (Directory.GetDirectories) und trimme die Ausgabe so das ich ein String-Array rausbekomme indem alle Namen der Unterverzeichnisse stehen. Ebendiese möchte ich dann als Auswahl in dem DataGridView wählen lönnen.
    Willkommen im Forum. :thumbup:

    jdoerr schrieb:

    alle Namen der Unterverzeichnisse
    So was:

    VB.NET-Quellcode

    1. Dim di() = New IO.DirectoryInfo("c:\temp").GetDirectories("*.*", IO.SearchOption.AllDirectories)
    2. Me.ListBox1.DataSource = di

    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!

    jdoerr schrieb:

    so das ich ein String-Array rausbekomme
    Wie gesagt: Ob nun Combobox oder DgvComboboxColumn (in deiner Rede unterscheidest du da nicht - der Unterschied ist aber wie zw. Haushuhn und Hamster) - ob nun DataTable oder String-Array - macht alles keinen Unterschied.

    Eher kritisch zu beäugen ist, dass dir evtl. alle möglichen Grundlagen fehlen, bezüglich Databinding und evtl sogar auch Datenmodellierung.
    Diese Tragik entsteht eiglich immer, wenn man sich an Datenbank-Zugriffe macht, ohne zuvor(!) mit Databinding vertraut zu sein.
    Danke erstmal für die Auskünfte. Habe zwischenzeitlich eine Lösung gefunden.

    VB.NET-Quellcode

    1. Private Sub updateArtikelList()
    2. Dim ArtikelNoCol As New DataGridViewTextBoxColumn
    3. Dim PruefplanCol As New DataGridViewComboBoxColumn
    4. Dim Directories() As String = Directory.GetDirectories(My.Settings.ProgPath)
    5. artikelDataTable.Clear()
    6. artikelDatabaseAdapter.Fill(artikelDataTable)
    7. dgvArtikel.Columns.Clear()
    8. dgvArtikel.AutoGenerateColumns = False
    9. dgvArtikel.DataSource = artikelDataTable
    10. With ArtikelNoCol
    11. .HeaderText = "Artikelnummer"
    12. .DataPropertyName = "artikelno"
    13. .Width = CInt(dgvArtikel.Width * 0.4)
    14. End With
    15. With PruefplanCol
    16. .HeaderText = "Prüfplan"
    17. .ValueMember = "pruefplan"
    18. .DataPropertyName = "pruefplan"
    19. For Each Directory As String In Directories
    20. Directory = Directory.Split(CChar("\")).Last
    21. .Items.Add(Directory)
    22. Next
    23. .Width = CInt(dgvArtikel.Width * 0.4)
    24. End With
    25. dgvArtikel.Columns.Add(ArtikelNoCol)
    26. dgvArtikel.Columns.Add(PruefplanCol)
    27. End Sub


    Die Thematik des DataBindings habe ich schon verstanden. Meine Problematik war, dass ich zunächst die Funktion von DataGridViewComboBoxColumn nicht durchschaut habe.
    Bisher habe ich DataGridViews nur in Verbindung mit stark typisierten DataSets verwendet und da konnte man ja alles über den Designer einstellen und der hat das gemanaged.
    Nur, da ich hier die Verzeichnisse erst zur Laufzeit auslese, kann ich diese eben erst zur Laufzeit an die ComoBox als Items binden. Allerdings mag ich keinen Mischmasch aus typiserten DataSet und codverwalteten DataSets, daher habe ich alles auf die Codeebene gezogen.
    @jdoerr Verzeichnisse gehören nach System.IO.DirectoryInfo, und die haben eine Property Parent.
    Nutze lieber die als das Split.
    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!
    My.settings.ProgPath ist ein von Anwender definierter Pfad der in keiner Relation zum Anwendungspfad liegt. (Ist vom Namen her ein wenig unklug gewählt ich weiß ;) )
    Das mit dem Split verstehe ich nicht ganz. Ich muss doch sowieso splitten sonst wird mir ja der komplette Pfad in der ComboBox angezeigt?
    Der Punkt ist, dass es etwas viel besseres gibt als die Directory-Klasse - nämlich die DirectoryInfo-Klasse. Damit könntest du deinen Code wie folgt umbauen:

    VB.NET-Quellcode

    1. Private Sub updateArtikelList()
    2. Dim ArtikelNoCol As New DataGridViewTextBoxColumn
    3. Dim PruefplanCol As New DataGridViewComboBoxColumn
    4. artikelDataTable.Clear()
    5. artikelDatabaseAdapter.Fill(artikelDataTable)
    6. dgvArtikel.Columns.Clear()
    7. dgvArtikel.AutoGenerateColumns = False
    8. dgvArtikel.DataSource = artikelDataTable
    9. With ArtikelNoCol
    10. .HeaderText = "Artikelnummer"
    11. .DataPropertyName = "artikelno"
    12. .Width = CInt(dgvArtikel.Width * 0.4)
    13. End With
    14. With PruefplanCol
    15. .HeaderText = "Prüfplan"
    16. .ValueMember = "Name"
    17. .DisplayMember = "Name"
    18. .DataPropertyName = "pruefplan"
    19. .DataSource = New DirectoryInfo(My.Settings.ProgPath).GetDirectories()
    20. .Width = CInt(dgvArtikel.Width * 0.4)
    21. End With
    22. dgvArtikel.Columns.Add(ArtikelNoCol)
    23. dgvArtikel.Columns.Add(PruefplanCol)
    24. End Sub
    probier ma aus.
    Und bei Interesse schau dir die DirectoryInfo-Klasse gründlich an, im ObjectBrowser (ich hoffe, du weisst, was das ist)
    Den Ansatz habe ich schonmal probiert. Was mir dabei allerdings Probleme bereitet hat, ist, dass ich der Zelle eine eigene DataSource gebe und die Zelle damit nicht die befüllte DataSource von dem DataGridView erbt. Ich kriege zwar so theoretisch mein Verzeichnisse als Einträge, aber mein ValueMember hat dann keinen Bezug mehr. Somit wählt mir das DataGridView nicht mehr den in der Datenbank gespeicherten Wert standartmäßig aus.
    dann probier nochmal - mit meim Code. Vlt haste in deim früheren Versuch was falsch gemacht (dass du DirectoryInfo nich tzu kennen scheinst, deutet darauf hin), und mit diesem hier klappts jetzt.

    Oder deine Info ist iwie unvollständig:
    dass ich der Zelle eine eigene DataSource gebe
    Davon war bislang nicht die Rede. Sondern vonne DataSource der DgvColumn.

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

    Meinte statt Zelle Column.

    VB.NET-Quellcode

    1. .ValueMember = "pruefplan"
    würde ja nichtmehr funktionieren da ja bei deiner Lösung die Ausgabe von DirectoryInfo in die DataSource geladen wird. Dementsprechend gibt es dann ja die Tabelle "pruefplan" nicht mehr.