Laden...

DataGridView: Typ der Collumn nach Bindung ändern

Erstellt von RioFuTa vor 3 Jahren Letzter Beitrag vor 3 Jahren 341 Views
R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren
DataGridView: Typ der Collumn nach Bindung ändern

Hallo,
ich abe eventuell nur ein Verständnispröblem ...

Ich nutze eine DataTable um die Daten für das DataGridView zu halten.

Die Definition:


            m_ServerDataTable = new DataTable();
            m_ServerDataTable.Columns.Add("Quelle");

            DataColumn columnInvalid = new DataColumn();
            columnInvalid.ColumnName = "Invalid";
            columnInvalid.DataType = typeof(MSP_MF);  // <- Enum
            m_ServerDataTable.Columns.Add(columnInvalid);

            DataColumn columnInverter = new DataColumn();
            columnInverter.ColumnName = "Inverter";
            columnInverter.DataType = typeof(bool);
            m_ServerDataTable.Columns.Add(columnInverter);

            m_ServerDataTable.Columns.Add("Senke");

Angebunden an das View:


            dataGridViewServerData.DataSource = m_ServerDataTable;

Die Spalte "Inverter" wird als Checkbox angezeigt.
In der Spalte "Invalid" wird leider nur der übergebene Text eingetragen, ich hätte eine Combobox mit der Auswahl aus dem Enum erwartet.

Kann ich nach der Bindung an die DataTable den Typ der Spalte auf "ComboBox" ändern?

Ich habe bisher nur Beispiele gefunden in welchen die Spalte im Vorfeld als Combobox formatiert wird und dann dem Grid zugefügt wurde.
Nun sind meine Daten aber dynamisch und die Spalte die ich als Auswahl haben möchte ändert sich.

Ist der Ansatz falsch oder wo liegt mein Fehler?

Gruß RioFuTa.

F
10.010 Beiträge seit 2004
vor 3 Jahren

Du erstellst ja irgendwo das DGV, und da musst du dann eben die entsprechenden DataGridViewComboBoxColumn erzeugen

R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren

Das DGV ist leer und ohne Datenquelle in Designer erstellt.
Die Spalten erstellen sich automatisch durch die Bindung an die DataTable.

Kann ich die Spalten im DGV vorher erstellen obwohl ich an ein DataTable binde?

F
10.010 Beiträge seit 2004
vor 3 Jahren

Natürlich, einfach AutoGenerateColumns auf false und los

R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren

Der Tipp ist gut.
Wusste ich noch nicht.

Ich habe die Spalten jetzt vorher angelegt:


            dataGridViewServerData.Columns.Clear();
            dataGridViewServerData.AutoGenerateColumns = false;

            DataGridViewColumn dgvc_source = new DataGridViewColumn();
            dgvc_source.HeaderText = "Quelle";
            dataGridViewServerData.Columns.Add(dgvc_source);

            DataGridViewComboBoxColumn dgvc_invalid = CreateComboBoxColumn("Invalid");
            dgvc_invalid.Items.AddRange("Keine", "Sig_1", "Sig_2", "Sig_3", "Sig_4", "Sig_5", "Sig_6");
            dgvc_invalid.HeaderText = "Invalid";
            dataGridViewServerData.Columns.Add(dgvc_invalid);

            DataGridViewCheckBoxColumn dgvc_inv2 = new DataGridViewCheckBoxColumn();
            dgvc_inv2.HeaderText = "Inverter";
            dataGridViewServerData.Columns.Add(dgvc_inv2);

            DataGridViewColumn dgvc_drain = new DataGridViewColumn();
            dgvc_drain.HeaderText = "Senke";
            dataGridViewServerData.Columns.Add(dgvc_drain);

Die Tablelle ist wie bisher nur ohne Spaltenbezeichner


            m_ServerDataTable = new DataTable();
            m_ServerDataTable.Columns.Add("");
            m_ServerDataTable.Columns.Add("");
            m_ServerDataTable.Columns.Add("");
            m_ServerDataTable.Columns.Add("");
            m_ServerDataTable.Rows.Add(new object[] { "xyz", "Keine", true, "abc" });
            m_ServerDataTable.Rows.Add(new object[] { "123", "Keine", true, "456" });

Bei der Bindung des DGV an die Tabelle


            dataGridViewServerData.DataSource = m_ServerDataTable;

erhalte ich eine Exception > Fehlermeldung:

System.InvalidOperationException: "Mindestens eine Spalte des DataGridView-Steuerelements hat keine Zellenvorlage."

Muss ich hier eventuell das DGV selber füllen und nicht den Weg über die DataTable nehmen?

R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren

Klappt.

Für die Textfelder


            DataGridViewTextBoxColumn dgvc_source = new DataGridViewTextBoxColumn();
            dgvc_source.HeaderText = "Quelle";
            dgvc_source.ValueType = typeof(string);
            dataGridViewServerData.Columns.Add(dgvc_source);

Für die Auswahlen


            DataGridViewComboBoxColumn dgvc_invalid = CreateComboBoxColumn("Invalid");
            dgvc_invalid.Items.AddRange(MSP_MF.Keine, MSP_MF.Sig_1, MSP_MF.Sig_2, MSP_MF.Sig_3, MSP_MF.Sig_4, MSP_MF.Sig_5, MSP_MF.Sig_6); 
            dgvc_invalid.HeaderText = "Invalid";
            dgvc_invalid.ValueType = typeof(MSP_MF);
            dataGridViewServerData.Columns.Add(dgvc_invalid);

Die Daten kommen ohne Tabelle direkt


            object[] row0 = { "xyz", MSP_MF.Keine, true, "abc" };
            dataGridViewServerData.Rows.Add(row0);

Vielen Dank für die Tipps.
👍

F
10.010 Beiträge seit 2004
vor 3 Jahren

Bitte nicht so machen.
Die Daten gehören nicht in das DGV sondern in eine Liste/DataTable.

Damit die jeweilige Column auch weis welche Spalte der DataTable gemeint ist, musst du nur MappingName setzen und dafür muss die Spalte natürlich auch einen namen haben

R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren

Die Datenhaltung per DataTable ist mir auch viel lieber.
Ich halte eh begleitend eine DataTable und synchronisiere die Daten über "CellValueChanged".

Ich habe die Styles angelegt.
Zwar kann ich keine "DataGrid<COMBOBOX>Column" auswählen, aber ich habe mal ersatzweise Text zugewiesen.


            DataGridTableStyle myGridStyle = new DataGridTableStyle();
            myGridStyle.MappingName = "Data";

            DataGridColumnStyle gsd_source = new DataGridTextBoxColumn();
            gsd_source.HeaderText = "Quelle";
            myGridStyle.GridColumnStyles.Add(gsd_source);

            DataGridColumnStyle gsd_invalid = new DataGridTextBoxColumn();
            gsd_invalid.MappingName = "Invalid";
            myGridStyle.GridColumnStyles.Add(gsd_invalid);

            DataGridColumnStyle gsd_inv2 = new DataGridBoolColumn();
            gsd_inv2.MappingName = "Inverter";
            myGridStyle.GridColumnStyles.Add(gsd_inv2);

            DataGridColumnStyle gsd_drain = new DataGridTextBoxColumn();
            gsd_drain.MappingName = "Senke";
            myGridStyle.GridColumnStyles.Add(gsd_drain);

Meine Tabelle hat wieder Spaltenbezeichner


            m_ServerDataTable.Columns.Add("Quelle");
            m_ServerDataTable.Columns.Add("Invalid");
            m_ServerDataTable.Columns.Add("Invert");
            m_ServerDataTable.Columns.Add("Senke");

Aber die Bindung an das DGV will nicht gelingen. Das Property "TableStyles" bleibt leider rot unterstrichen.


            dataGridViewServerData.TableStyles.Add(myGridStyle);

4.942 Beiträge seit 2008
vor 3 Jahren

DataGridColumnStyle gehört zum (veralteten) DataGrid, nicht zur DataGridView.

Du mußt nur für jede Spalte die Eigenschaft DataPropertyName auf die zugehörige DataTable-Spalte mappen.
Schau dir mal das Code-Beispiel der Antwort in Create DataGridView column that maps value from datasource (SetGridColumns) an.

R
RioFuTa Themenstarter:in
6 Beiträge seit 2021
vor 3 Jahren

Klappt. -> Klasse.

Mit dem Mapping auf die Tabellenspalten klappt es hervoragend und ich muss keine Datan im DGV halten


            DataGridViewTextBoxColumn dgvc_source = new DataGridViewTextBoxColumn();
            dgvc_source.HeaderText = "Signalquelle";
            dgvc_source.DataPropertyName = "Quelle";
            dgvc_source.ValueType = typeof(string);
            dataGridViewServerData.Columns.Add(dgvc_source);

Danke für die Hilfe.