Reputation: 1734
What I'm trying to do is making
I read this toturial and made my own DataGridViewBarColumn, but I don't have the slightest clue how I should implement something like this.
Performance doesn't matter even though there can be upwards of 100K rows in a DataGridView, I'll take care of optimizations later.
I think they're done the same way, so I'm asking them in one question
Upvotes: 1
Views: 420
Reputation: 2535
What I can give you is a starting point to achieve it:
First, Prepare your binding and create your DataGridViewComboBoxColumn.
private List<string> list = new List<string>();
public Form1()
{
InitializeComponent();
// Data source for you dropdown list
list.Add("First Option");
list.Add("Second Option");
list.Add("Third Option");
dataGridView1.AutoGenerateColumns = false;
dataGridView1.MultiSelect = false;
dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
dataGridView1.CellValidating += new DataGridViewCellValidatingEventHandler(dataGridView1_CellValidating);
dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing);
dataGridView1.DataError += dataGridView1_DataError;
// Formatting your ComboBox
DataGridViewComboBoxColumn comboColumn = new DataGridViewComboBoxColumn();
comboColumn.FlatStyle = FlatStyle.Flat;
comboColumn.HeaderText = "Hybrid Data Grid Column";
comboColumn.DataPropertyName = "Tag";
//comboColumn.DataSource = list;
dataGridView1.Columns.Add(comboColumn);
dataGridView1.DataSource = list;
}
Second, Attached an event for editing once you type:
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
var combo = ((DataGridView)sender).CurrentCell as DataGridViewComboBoxCell;
if (combo == null)
{
return;
}
if (!combo.Items.Contains(e.FormattedValue))
{
// Add the text you type into you bound list and refresh binding
list.Add(e.FormattedValue.ToString());
DataGridViewComboBoxColumn col = ((DataGridView)sender).CurrentCell.OwningColumn as DataGridViewComboBoxColumn;
col.Items.Clear();
col.Items.AddRange(list);
}
// Display what you type
((DataGridView)sender).CurrentCell.Value = e.FormattedValue;
}
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox comboControl = e.Control as ComboBox;
if (comboControl != null)
{
if (comboControl.DropDownStyle != ComboBoxStyle.DropDown)
{
comboControl.DropDownStyle = ComboBoxStyle.DropDown;
}
//Update Items if list has changed (assumes items can't be deleted)
if (comboControl.Items.Count != list.Count)
{
DataGridViewComboBoxColumn col = ((DataGridView)sender).CurrentCell.OwningColumn as DataGridViewComboBoxColumn;
col.Items.Clear();
col.Items.AddRange(list.ToArray());
//Note: current cell's items don't appear to be refreshed by the lines above
comboControl.Items.Clear();
comboControl.Items.AddRange(list.ToArray());
}
}
}
Sample Output:
Note : Since we are adding text input in our bound list it might happen that once you click to dropdown option you will see the additional input. So, I will leave it to you to polish it up.
Upvotes: 2