I would like to have a column of ComboBoxes in a DataGridView, which allows the user to freely input some text, which is collected in the dropdown menus, so that entering the same text in the next box is faster. I'd prefer not to use DataGridViewComboBoxColumn, unless I really have to.
The following code nearly does the job but has these issues:
After entering some new text and hitting return, the newly entered text is immediately replaced with the old value
But the new text is successfully added to the dropdown menus of all of the comboboxes
when I select this newly added text in one of the boxes, I get DataGridView-Exceptions complaining about an invalid value.
It seems the boxes somehow have for validation purposes a copy of the datasource which doesn't get updated?
public partial class Form1 : Form
{
List<string> data = new List<string>(); // shared data source for all ComboBoxes
private void checkData(string s) // check wether s in the list, add it if not, keep things sorted
{
if (data.Contains(s))
return;
data.Add(s);
data.Sort();
}
private void addCell(string s) // add a new cell to the grid
{
checkData(s);
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.DataSource = data;
c.Value = s;
int i = theGrid.Rows.Add();
theGrid.Rows[i].Cells[0] = c;
}
public Form1()
{
InitializeComponent();
theGrid.ColumnCount = 1;
addCell("Foo");
addCell("Bar");
}
// handler to enable the user to enter free text
private void theGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox cb = e.Control as ComboBox;
if (cb != null)
cb.DropDownStyle = ComboBoxStyle.DropDown;
}
// handler which adds the entered text to the data source
private void theGrid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.RowIndex < 0 || e.ColumnIndex < 0)
return;
checkData(e.FormattedValue.ToString());
}
}