2016-07-11 19 views
0

Haben Sie datagridview, die 4 Spalten enthält, die manuell vom Ersteller erstellt wurden. 1., 2. und 3. Spalte sind nur Textbox-Spalten, aber die letzte Spalte ist als Combobox-Spalte markiert.DataGridView-Combobox-Spalte mit Datenquelle

Benutzer kann Zeilen hinzufügen, klickt auf einige Schaltfläche. Die Werte für die ersten drei Spalten stammen von einigen Textfeldern. Das Problem ist, ich muss combobx Spalte auffüllen, wenn Benutzer seine Zeile hinzufügen. Was ich versucht, so war weit wie folgt aus:

dgvMaterials.Rows.Add(material, rodzajName, rodzajID, new Variation().GetAll()) 

Beachten Sie, dass GetAll Funktion retreiving innerhalb Datentabelle Daten ID und den Namen. Die ID sollte als Wertelement und Name als Anzeigeelement markiert sein.

So einfach gesagt, Benutzer klicken Sie auf eine Schaltfläche in Formularbaum erste Spalte Felder aus einigen Textfelder füllen, und letzte Combobox-Spalte sollte durch Daten von GetAll gefüllt werden. Wie erreiche ich das?


Private Sub btnAddMatType_Click(sender As Object, e As EventArgs) Handles btnAddMatType.Click 

      try 
       Dim dt as DataTable 
       dt = New Variation().GetAll() 


       Dim cbo = CType(dgvMaterials.Columns(3), DataGridViewComboBoxColumn) 
       cbo.Items.AddRange(dt.AsEnumerable().Select(Function(s) s.Field(Of String)("Name")).ToArray()) 

       Dim rodzajID as String = TreeMaterials.SelectedValue 
       Dim rodzajName as string = TreeMaterials.SelectedNode.Text 
       Dim material as string = TreeMaterials.SelectedNode.Parent.Text 

       dgvMaterials.Rows.Add(material, rodzajName, rodzajID) 


Catch ex As Exception 
       msgbox(ex.ToString()) 
End Try 

dt enthält Daten: enter image description here

Gitter sehen, nachdem alle (keine Daten in Combo): enter image description here

in cbo.Items Bohren: enter image description here

+0

a) Was ist nichts (Mauszeiger)? Es muss "cbo" oder "dt" sein. Gibt es im DGV Design eine cbo? Haben Sie die Eigenschaft name auf "Wariacja" gesetzt? Beides würde bedeuten, dass cbo null ist. b) ** ** Übergeben Sie nicht den cbo in der 'Rows.Add', übergeben Sie den Wert dieser Eigenschaft, wenn es einen gibt. Beachten Sie in meinem, dass der erste einen vierten Datenelementpunkt hat, die anderen nicht. – Plutonix

+0

@JimmyJimm Kompiliert das 'Dim cbo als DataGridViewComboBoxColumn = Me.Wariacja'? (oder wie auch immer ist der Name der ComboBoxColumn) – Slai

+0

Beachten Sie, dass es zwei Klicks benötigt, um diese Dinge zu öffnen. Der erste Klick ist die ausgewählte Zeile/Zelle - Sie sehen den Zeilenkopf Pfeilsprung - der zweite öffnet die cbo – Plutonix

Antwort

1

Wenn Sie haben die Spalten selbst erstellt, Sie müssen nur die cbo hinzufügen Daten.

Dim sql = "SELECT Id, Name FROM Foo" 
Dim dt = ... get the dt from db 

' cast column 3/Foo to CBO column to access CBO related props 
Dim cbo = CType(dgv2.Columns("FooCol"), DataGridViewComboBoxColumn) 
cbo.DataSource = dt 
cbo.ValueMember = "Id" 
cbo.DisplayMember = "Name" 

Dies wird jedoch nicht gut funktionieren, ohne DataSource wie ein List oder DataTable für die DGV - es gibt keinen Ort, um die Id zu speichern. Es wäre einfach, eine kleine Klasse und eine Liste dafür aufzustellen, aber es könnte auch zu viel werden.

Statt, da Sie manuell die DGV füllen, füllen Sie einfach die Items Sammlung als well.This Code, um die Liste für die gesamte Spalte einrichtet, so sollte es nur einmal ausgeführt werden:

Dim cbo = CType(dgv2.Columns("FooCol"), DataGridViewComboBoxColumn) 
' get all the names to be used 
cbo.Items.AddRange(dt.AsEnumerable(). 
        Select(Function(s) s.Field(Of String)("Name")). 
        ToArray()) 

Das Hinzufügen von Zeilen beinhaltet einfach das Hinzufügen einer neuen Zeile. Für die CBO-Spalte, würden Sie eine Zeichenkette, die die aktuelle Auswahl passieren, oder es überspringen vielleicht für eine neue Reihe:

' add one or more rows - no Foo data yet 
dgv2.Rows.Add("Ziggy", "Orange", 1, "Cat") 
dgv2.Rows.Add("Zoey", "Blue", 3) 
dgv2.Rows.Add("Zalgo", "Green", 78) 

Beachten Sie, dass die Sammlung Items bevölkern ist eine einmalige Sache. Sie können Zeilen hinzufügen/entfernen, wenn der Benutzer Dinge auswählt, aber die cbo muss nur einmal eingerichtet werden.

Wenn es Daten für foo gibt - einen der Werte von DataTable - liefern Sie es. Ungebunden, müssen Sie möglicherweise die DataTable halten, damit Sie den Wert/ID für den ausgewählten Text nachschlagen können. Ergebnis:

enter image description hereenter image description here


Eine weitere Alternative wäre, die TreeView Daten zu einem Klassenobjekt zu kopieren und ein PropertyGrid verwenden, wenn Sie gerade bearbeitet, ein Element zu einem Zeitpunkt.Dies würde es einem TypeConverter ermöglichen, eine Sache anzuzeigen und eine andere zu speichern, als eine datengebundene Kontrolle würde.

+0

siehe Hauptpost agai ich verwendet von Index jetzt und jetzt bekomme ich einen Fehler in dieser Zeile: dgvMaterials.Rows.Add (Material, rodzajName, rodzajID, "Farbe") sagt : Im Format von Datagridview gab es folgende Ausnahme: System.FormatException. Wert od datagridviewcomboboxcell ist nicht korrekt –

+0

Yup und es sollte. Bitte lesen Sie die Antwort sorgfältig durch: Der DGV ist nicht gebunden, so dass es keinen Wert gibt, ein ValueMember/Id zu speichern, weshalb Sie die 'Items.AddRange' Methode verwenden müssen. Wenn Sie die Daten nicht in eine Liste , scheinbar für ein Element, einbinden möchten, wird der Benutzer ein Element auswählen, und Sie werden die ID nachschlagen. Anders als beim DGV-Setup [das ist buchstäblich der ganze Code, den ich dafür habe, dass es funktioniert] (http://pastebin.com/qQV5Ar9J). Verwenden Sie die Datentabelle später, um die ID zu erhalten – Plutonix