Hallo,
ich verzweifel gerade wieder fast an einem Problem, bei dem mir alles, was ich im Nezt finden konnte, nicht wirklich weitergeholfen hat.
Ich habe ein DataGridView mit einer Zeile und n Spalten. In jeder Zelle steht entweder 0, 1 oder -1. Nun möchte ich einfach den Wert der Zelle abfragen und durch eine ComboBox-Zelle ersetzen, die es mir erlaubt, 0, + oder - auszuwählen.
Das Auslesen des Wertes bekomme ich noch gebacken. Aber wie mache ich daraus dann eine ComboBox-Zelle und wie setze ich innerhalb dieser den Index??
Ich hoffe mal, ihr habt eine Idee!?
Hi binärathlet,
Gruß
Also ich würde es in etwa so machen:
#region Create and fill the main data table
// Tabelle mit den eigentlichen Daten
DataTable mainData = new DataTable("Main";);
mainData.Columns.Add("FirstName", typeof(string));
mainData.Columns.Add("LastName", typeof(string));
DataRow person1 = mainData.NewRow();
person1["FirstName"] = "Joe";
person1["LastName"] = "Satriani";
DataRow person2 = mainData.NewRow();
person2["FirstName"] = "Juergen";
person2["LastName"] = "Drews";
mainData.Rows.Add(person1);
mainData.Rows.Add(person2);
mainData.AcceptChanges();
#endregion Create and fill the main data table
#region Create and fill additional data table
// Tabelle mit den Werten fuer die ComboBox
DataTable additionalData = new DataTable("Additional";);
additionalData.Columns.Add("Rating", typeof(string));
DataRow awesomeRating = additionalData.NewRow();
awesomeRating["Rating"] = "Awesome";
DataRow goodRating = additionalData.NewRow();
goodRating["Rating"] = "Good";
DataRow terribleRating = additionalData.NewRow();
terribleRating["Rating"] = "Terrible";
additionalData.Rows.Add(awesomeRating);
additionalData.Rows.Add(goodRating);
additionalData.Rows.Add(terribleRating);
additionalData.AcceptChanges();
#endregion Create and fill the additional table
#region Create and fill dataSet
DataSet dataSet = new DataSet();
dataSet.Tables.Add(mainData);
dataSet.Tables.Add(additionalData);
#endregion Create and fill dataSet
#region Create and fill the ComboBox-Column
DataGridViewComboBoxColumn ratingColumn = new DataGridViewComboBoxColumn();
ratingColumn.Name = "Rating";
ratingColumn.HeaderText = "Rating";
ratingColumn.HeaderCell.Value = "Rating";
ratingColumn.DataPropertyName = "Rating";
ratingColumn.DataSource = dataSet.Tables["Additional"];
ratingColumn.ValueMember = dataSet.Tables["Additional"].Columns["Rating"].ColumnName;
ratingColumn.DisplayMember = dataSet.Tables["Additional"].Columns["Rating"].ColumnName;
#endregion Create and fill the ComboBox-Column
#region Bind data to the grid and attach a comboBoxColumn
this.dataGridView.DataSource = dataSet;
this.dataGridView.DataMember = dataSet.Tables["Main"].TableName;
this.dataGridView.Columns.Add(ratingColumn);
this.dataGridView.ReadOnly = false;
#endregion Bind data to the grid and attach a comboBoxColumn
#region Set custom values for 'Rating' cells
DataGridViewComboBoxCell person1ComboBoxCell = (this.dataGridView.Rows[0].Cells["Rating"] as DataGridViewComboBoxCell);
person1ComboBoxCell.Value = ((DataTable)person1ComboBoxCell.DataSource).Rows[0]["Rating"];
DataGridViewComboBoxCell person2ComboBoxCell = (this.dataGridView.Rows[1].Cells["Rating"] as DataGridViewComboBoxCell);
person2ComboBoxCell.Value = ((DataTable)person1ComboBoxCell.DataSource).Rows[2]["Rating"];
#endregion Set custom values for 'Rating' cells
if (extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value != null)
{
if (extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "Yes" || extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "No")
{
// ------------------------------------------------
// Create an new ComboBoxCell
DataGridViewComboBoxCell cbo1 = new DataGridViewComboBoxCell();
// Add Items to the ComboBox
cbo1.Items.Add("Yes");
cbo1.Items.Add("No");
// Set the displayed value.
// This value needs to be present
// in the items collection
cbo1.Value = (extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "No" ? cbo1.Items[1] : cbo1.Items[0]);
cbo1.FlatStyle = FlatStyle.Standard;
cbo1.MaxDropDownItems = 3;
// Save the CurrentCell
curCell = extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex];
// Set the Value into the DGVCell
extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
// DataGridViewCell = DataGridViewComboBoxCell
extDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex] = cbo1;
}
Vielleicht hilft dir das ne Stück weiter
Hallo recmar,
danke, genau sowas hab ich gesucht. Allerdings funktioniert meine Interpretation deines Vorschlages noch nicht wirklich, da ständig das DataError-Ereignis abgefeuert wird und die ComboBox schließlich nicht angezeigt wird !?
Hier der Code dazu:
// Spalten durchlaufen
for (int i = 0; i < objInstance.grdDataGrid.Rows.Count; i++)
{
// Zeilen durchlaufen
for (int j = 1; j < objInstance.grdDataGrid.Columns.Count; j++)
{
if (objInstance.grdDataGrid.Rows[i].Cells[j].Value != null)
{
// ComboBox - Zelle anlegen
DataGridViewComboBoxCell vComboCell = new DataGridViewComboBoxCell();
vComboCell.Items.AddRange(new object[3] {"++", "o", "--"});
// Index auswählen
if (objInstance.grdDataGrid.Rows[i].Cells[j].Value.ToString() == Convert.ToString(1))
vComboCell.Value = vComboCell.Items[0];
else if (objInstance.grdDataGrid.Rows[i].Cells[j].Value.ToString() == Convert.ToString(-1))
vComboCell.Value = vComboCell.Items[2];
else
vComboCell.Value = vComboCell.Items[1];
// Anzeige festlegen
vComboCell.FlatStyle = FlatStyle.Standard;
vComboCell.MaxDropDownItems = 3;
// Datentyp festlegen
objInstance.grdDataGrid.Rows[i].Cells[j].Value = objInstance.grdDataGrid.Rows[i].Cells[j].Value.ToString();
// ComboBox - Zelle setzen
objInstance.grdDataGrid.Rows[i].Cells[j] = vComboCell;
}
}
}
probierma
Der frühe Apfel fängt den Wurm.
Hallo ErfinderDesRades,
danke für den Code, aber langsam glaube ich wirklich, ich bin zu dämlich, das zu kapieren. In dieser (in Anlehnung an deinen Code) gehaltenen Version laufe ich erstens in eine ArgumtentException und zweitens habe ich immernoch nicht verstanden, wozu ich die BindingSource brauche bzw. wie es ohne ginge ....
BindingSource vSource2 = new BindingSource();
vSource2.Add(new object[3] { "++", "o", "--" });
DataGrid.DataSource = vSource2;
DataGrid.AutoGenerateColumns = false;
DataGrid.AutoSize = true;
for (int i = 1; i < 10; i++)
{
DataGrid.Columns.Add(CreateComboBox("TEST"));
}
private DataGridViewComboBoxColumn CreateComboBox(string vTitle)
{
DataGridViewComboBoxColumn vCombo = new DataGridViewComboBoxColumn();
vCombo.DataSource = Enum.GetValues(typeof(String)); // --> ArgumentException
vCombo.DataPropertyName = vTitle;
vCombo.Name = vTitle;
return vCombo;
}
schau dir nochmal genau an, welchen Typ ich bei Enum.GetValues() übergebe.
Der frühe Apfel fängt den Wurm.
aha .... jetzt funzts, danke fürs 'Nase-auf-die-Lösung-drücken' 😁
wenn du mir jetzt noch sagen könntest, wie ich den Index festlege, wäre ich vollends glücklich ...
DataGrid.Columns.Clear();
DataGrid.AutoGenerateColumns = false;
DataGrid.AutoSize = true;
for (int i = 1; i < 10; i++)
{
objInstance.grdDataGrid.Columns.Add(CreateComboBox("TEST"));
}
private DataGridViewComboBoxColumn CreateComboBox(string vTitle)
{
DataGridViewComboBoxColumn vCombo = new DataGridViewComboBoxColumn();
vCombo.DataSource = new object[4] { "HUND", "KATZE", "MAUS", "OTZELOT" };
vCombo.DataPropertyName = vTitle;
vCombo.Name = vTitle;
return vCombo;
}
Hallo Binärathlet,
wenn du mir jetzt noch sagen könntest, wie ich den Index festlege
dir wurden drei Lösungsvorschläge (fast schon Musterlösungen) presentiert und die Antwort auf deine Frage ist defenitiv dabei... Du musst dich jetzt auch mal anstrengen!
😄
gut, die DataGridViewComboBoxCell kenn ich jetzt in- und auswendig und kann sogar den Index setzen 😁 ... aber bei der DataGridViewComboBoxColumn krieg ich es ums Verrecken nicht hin. Keine Ahnung was ich falsch mach, aber ich bekomm es nicht gebacken 8o 8o
Naja vCombo.Index ist Read-Only. Hast dus mal mit vCombo.DisplayIndex probiert? Naja das wird dir vermutlich nicht viel helfen, da es ja nur die angezeigte Reihenfolge beeinfluss.
Wozu willst du den Index der Column eigentlich selbst bestimmen?
DisplayIndex bringt auch nichts. Ich will doch nur festlegen, was in diesem DropDown-Element ausgewählt erscheint, wenn man es öffnet, das muss doch möglich sein oder!?
Aber es gibt ja scheinbar auch nicht wirklich eine Möglichkeit, die Zellen der DataGridViewComboBoxColumn zu durchlaufen und in der jeweiligen Celle den Index zu setzen!?
scheinbar bin ich der Einzige, ders nicht kapiert 🤔
// Spalte hinzufügen
DataGridView.Columns.Add(mCreateComboBox(vGridData.Columns[i].ColumnName);
// Spalte generieren
private DataGridViewComboBoxColumn mCreateComboBox(string vTitle)
{
DataGridViewComboBoxColumn vCombo = new DataGridViewComboBoxColumn();
vCombo.DataSource = new object[3] { "ja", "nein", "vielleicht" };
vCombo.DataPropertyName = vTitle;
vCombo.Name = vTitle;
vCombo.MaxDropDownItems = 3;
vCombo.FlatStyle = FlatStyle.System;
int i,j = 0; //Zeile und Spalte
datagridview1.Rows[i].Cells[j].Value = "ja";
//oder
//datagridview1.Rows[i].Cells[j].Value = "nein";
//oder
//datagridview1.Rows[i].Cells[j].Value = "vielleicht";
je nachdem was du eben willst und wohin es soll. Wenn du es über einen Index haben willst wirst du wohl den Weg über Enums von ErfinderDesRades nehmen müssen.
Wenn das so funktionieren würde, würde es mir schon reichen, aber leider scheint das nicht zu gehen:
// Spalte hinzufügen
DataGridView.Columns.Add(mCreateComboBox(vGridData.Columns[i].ColumnName);
// Index setzen (erste Spalte, erste Zeile)
DataGridView.Rows[0].Cells[0].Value = "nein";
// Spalte generieren
private DataGridViewComboBoxColumn mCreateComboBox(string vTitle)
{
DataGridViewComboBoxColumn vCombo = new DataGridViewComboBoxColumn();
vCombo.DataSource = new object[3] { "ja", "nein", "vielleicht" };
vCombo.DataPropertyName = vTitle;
vCombo.Name = vTitle;
vCombo.MaxDropDownItems = 3;
vCombo.FlatStyle = FlatStyle.System;
}
Die Werte sind zwar in der Zelle hinterlegt, nur sieht das ganze trotz Setzen des Indexes so aus:
Das ist merkwürdig. Bei mir gehts. Es ist nicht zufällig die ForeColor gleich der BackColor? Nur um das einfachste mal auszuschließen. 😁
Bzw. ist das angelegte auch Cells[0]? Keine anderen Columns davor?
Funktioniert das Dropdownmenü beim drauf drücken? Die 3 Einträge sollten ja angezeigt werden?
loool, jetzt habe ich mir das ganze nochmal in einem primitiven Beispiel nachgebaut und auch da gehts. Scheinbar liegt dann das Problem irgendwo im restlichen Code. Naja, dann weiß ich jetzt zumindest, dass ich an der falschen Stelle suche 😁
Jedenfalls danke für deine Geduld !! 👍 👍
Also dieses Ding schafft mich noch. Jetzt funktioniert endlich die Auswahl des Indexes, wenn ich nun aber dem Nutzer verbiete, Zeilen hinzuzufügen oder zu löschen, enthält das DataGridView auf einmal gar keine Einträge mehr
public partial class GridForm : Form
{
public GridForm()
{
InitializeComponent();
this.gridView.Columns.Clear();
this.gridView.AutoGenerateColumns = false;
this.gridView.AutoSize = false;
for (int i = 0; i <= 10; i++)
{
gridView.Columns.Add(mCreateComboBox("TEST"));
}
for (int i = 0; i <= 10; i++)
{
if (i % 2 == 0)
gridView.Rows[0].Cells[i].Value = "nein";
else
gridView.Rows[0].Cells[i].Value = "vielleicht";
}
// --> Diese zwei Zeilen führen dazu, dass die DataGridView überhauptkeine Spalten und Zeilen mehr enthält
this.gridView.AllowUserToAddRows = false;
this.gridView.AllowUserToDeleteRows = false;
}
private DataGridViewComboBoxColumn mCreateComboBox(string vTitle)
{
// ComboBox initialisieren
DataGridViewComboBoxColumn vCombo = new DataGridViewComboBoxColumn();
vCombo.DataSource = new object[3] { "ja", "nein", "vielleicht" };
vCombo.DataPropertyName = vTitle;
vCombo.Name = vTitle;
vCombo.MaxDropDownItems = 3;
vCombo.FlatStyle = FlatStyle.System;
return vCombo;
}
}
Lass mich raten. Vorher hattest du genau eine Zeile?
Du musst natürlich alle Zeilen dann vom Programm erzeugen lassen. Also
this.gridView.Rows.Add()
@Binärathlet:
Welchen Teil von gebundenen Wert hast du nicht verstanden?
Anscheinend den gesamten Satz.
Du sollst die Daten nicht ins Grid frickeln, sondern die Daten Binden ( DataTable?! )
DataGridView.AllowUserToAddRows-Eigenschaft
Und hier siehst du unter Hinweis das es eine Eigenschaft ist, die bei gebundenen Daten benutzt wird.
@Binärathlet,
wenn ich nun aber dem Nutzer verbiete, Zeilen hinzuzufügen oder zu löschen, enthält das DataGridView auf einmal gar keine Einträge mehr
für das Grid ist es das gleiche als hättest du es implicit auf "ReadOnly" gesetzt, vermutlich bleben die ComboBoxen deswegen leer.
BITTE, BITTE, BITTE schaue dir doch ENDLICH die Lösungsvorschläge an die dir Community gibt !!! ErfinderDesRades, recmar, und meine wenigkeit hatten dir schon vor 2 Wochen funktionierende Beispiele angeboten (sogar mit Databinding und Indexsetzen) !!! Auch FZelle gibt dir einen sehr wertvollen Tipp
Du sollst die Daten nicht ins Grid frickeln, sondern die Daten Binden ( DataTable?! )
Einfach nur systematisch die gegebene Info durcharbeiten...
Passendes Schlusswort von yngwie. Alle nötigen Infos wurde mehrfach genannt.