我可以给你一个起点上实现它:
首先,准备好你的约束力,创建你的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;
}
其次,附加的事件进行编辑,一旦你键入:
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());
}
}
}
样本输出:
注:由于我们是在我们的绑定添加文本输入列出它可能会发生,一旦你点击下拉选项,你会看到额外的输入。所以,我会把它交给你来打磨它。
我知道有http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewComboBoxCell.cs,它具有像内部重写void CacheEditingControl()这样的黑魔法。有没有人在少于4k条意大利面条线上使用可用许可证来做任何清洁工作? – Behrooz
我相信这个问题可能对你有用:http://stackoverflow.com/questions/986233/windows-forms-datagridview-control-have-different-control-types-in-the-same-colu你可能有潜在的使用它作为自定义DataGridViewHybridColumn的起点,因为它应该让您按单元格而不是按列选择单元格类型。 – Calcolat
@Calcolat我正在做那里已经说过的东西,目前它接近10K行代码,因为mono和.net在它们的实现中都使用了内部和内部保护方法,所以我不得不重新实现很多东西。 – Behrooz