Introduction
Implementing a DataGridViewComboBoxCell which hosts a
DataGridViewComboBoxEditingControl
can be quite challenging and it may take a great deal of effort and error testing before the
application starts behaving as expected.
Here we will show a way to implement a DataGridViewComboBoxCell
in a DataGridView control. The ComboBox control is populated with strings, which are editable.
(A more advanced data source will be discussed in a later guide).
A Simple DataGridView Example
We will implement a DataGridView with three rows and two columns, see figure 1 below. The left column will work as
a description for the right column. On the right column, the rows contain a TextBox cell,
a ComboBox cell and another TextBox cell.
Figure 1. Embedded ComboBox
In the listing below is a project in Visual Studio 2005 with an added
empty DataGridView control. We now add code to create the columns, rows and embedded controls.
The code is added to the Form1 constructor, just after
InitializeComponent().
Once we have added a ComboBox cell to the DataGridView, we want to influence the way the embedded
ComboBox control works. The only way to do this is by handling the
EditingControlShowing event.
In order to make the control editable, the DropDownStyle needs to be set to
DropDown.
When the user edits the displayed text in the ComboBox, we (in this case) want the edited
text to be added to the item collection and also be set as the
new displayed text. We therefore handle one of the events
being raised when we are finished editing the text by clicking somewhere else,
the CellValidating event. By capturing this event,
we can add any desired validation code. If the validation fails, then it is simple to
cancel the event and maybe display a message.
If the user added text should be displayed directly when we are
finished editing it (which is usually the case), it is necessary to
manually commit the changes. This code should also be put in
the CellValidating handler, see the inline code comments.
namespace ComboBoxTest {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
dataGridView1.BorderStyle = BorderStyle.Fixed3D;
dataGridView1.CellValidating +=
new DataGridViewCellValidatingEventHandler
(dataGridView1_CellValidating);
dataGridView1.EditingControlShowing +=
new DataGridViewEditingControlShowingEventHandler
(dataGridView1_EditingControlShowing);
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
dataGridView1.Columns.Add("NameOne", "Column One");
dataGridView1.Columns.Add("NameTwo", "Column Two");
DataGridViewRow dataGridRow = new DataGridViewRow();
DataGridViewCell[] cells = new DataGridViewCell[2];
DataGridViewTextBoxCell txt1A = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell txt1B = new DataGridViewTextBoxCell();
txt1A.Value = "textbox one";
txt1B.Value = "content one";
dataGridRow.Cells.Add(txt1A);
txt1A.ReadOnly = true;
dataGridRow.Cells.Add(txt1B);
dataGridRow.Height = 20;
dataGridView1.Rows.Add(dataGridRow);
dataGridRow = new DataGridViewRow();
cells = new DataGridViewCell[2];
DataGridViewTextBoxCell txt2A = new DataGridViewTextBoxCell();
DataGridViewComboBoxCell cbo1 = new DataGridViewComboBoxCell();
cbo1.Items.Add("Item one");
cbo1.Items.Add("Item two");
cbo1.Items.Add("Item three");
cbo1.Value = cbo1.Items[0];
cbo1.ReadOnly = false;
txt2A.Value = "a combobox";
dataGridRow.Cells.Add(txt2A);
txt2A.ReadOnly = true;
dataGridRow.Cells.Add(cbo1);
dataGridRow.Height = 20;
dataGridView1.Rows.Add(dataGridRow);
dataGridRow = new DataGridViewRow();
cells = new DataGridViewCell[2];
DataGridViewTextBoxCell txt3A = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell txt3B = new DataGridViewTextBoxCell();
txt3A.Value = "textbox two";
txt3B.Value = "content two";
dataGridRow.Cells.Add(txt3A);
dataGridRow.Cells.Add(txt3B);
dataGridRow.Height = 20;
dataGridView1.Rows.Add(dataGridRow);
}
private void dataGridView1_EditingControlShowing
(object sender,
DataGridViewEditingControlShowingEventArgs e) {
DataGridViewComboBoxEditingControl comboControl
= e.Control as DataGridViewComboBoxEditingControl;
if (comboControl != null) {
if (comboControl.DropDownStyle != ComboBoxStyle.DropDown) {
comboControl.DropDownStyle = ComboBoxStyle.DropDown;
}
}
}
private void dataGridView1_CellValidating
(object sender, DataGridViewCellValidatingEventArgs e) {
DataGridViewComboBoxCell cell =
dataGridView1.CurrentCell as DataGridViewComboBoxCell;
if (cell != null &&
!cell.Items.Contains(e.FormattedValue)) {
cell.Items.Insert(0, e.FormattedValue);
if (dataGridView1.IsCurrentCellDirty) {
dataGridView1.CommitEdit
(DataGridViewDataErrorContexts.Commit);
}
cell.Value = cell.Items[0];
}
}
}
}
|