我想要一个 DataGridView
的列使用 ComboBoxStyle.DropDown
样式 ComboBox,用户可以在其中选择下拉列表中的条目之一,或键入任意文本。
目前,我正在使用 this answer 中的代码我可以在 ComboBox 的文本框部分自由输入,但如果我输入的内容不在下拉列表中,则它不会提交回数据源,并且该字段将恢复为原始选择。此外,如果我以编程方式将文本设置为不在下拉列表中的内容,我会得到 DataError
。事件“DataGridViewComboBoxCell 值无效。”
我正在使用数据绑定(bind); DataGridView
本身绑定(bind)到 BindingList<T>
.
不同于this question我不想将自由文本添加到下拉列表中。
明确一点,列的数据类型是string
而且我不希望它根据 ComboBox 的下拉列表(或与此相关的任何其他内容)进行验证。
(我是否必须按照 How to: Host Controls in Windows Forms DataGridView Cells 中的描述创建自己的自定义 DataGridViewColumn
后代?)
最佳答案
我找到了一个简单但冗长的答案。 (但我仍然想知道是否有办法用标准的 DataGridViewComboBoxColumn
类型来做到这一点。)
我按照How to: Host Controls in Windows Forms DataGridView Cells中的方法做了.我的完整解决方案太长,无法在此处发布,但我可以总结一下所做的更改,使其使用 ComboBox
而不是示例的 DateTimePicker
控件。
分别重命名三个类
DropDownComboBoxColumn
、DropDownComboBoxCell
和DropDownComboBoxEditingControl
。用
string
替换所有地方的DateTime
。添加属性
public ComboBoxStyle DropDownStyle { get;放;
到DropDownComboBoxColumn
以允许调用代码设置下拉样式。从
DropDownComboBoxCell
构造函数中删除代码。从
DropDownComboBoxEditingControl
构造函数中删除代码。使
DropDownComboBoxEditingControl
派生自ComboBox
而不是DateTimePicker
。将
OnValueChanged
替换为OnTextChanged
以说明ComboBox
与DateTimePicker
中的不同命名。使
EditingControlFormattedValue
属性获取和设置继承的Text
属性(而不是Value
)并且不需要解析。使
ApplyCellStyleToEditingControl
设置ForeColor
和BackColor
而不是CalendarForeColor
和CalendarMonthBackground
.使
EditingControlWantsInputKey
也声明 F4,以便它可用于打开和关闭下拉菜单。将以下代码添加到
PrepareEditingControlForEdit
:DropDownComboBoxColumn col = _dataGridView.Columns[_dataGridView.CurrentCell.ColumnIndex] as DropDownComboBoxColumn; if (col == null) { throw new InvalidCastException("Must be in a DropDownComboBoxColumn"); } DropDownStyle = col.DropDownStyle; // (If you don't explicitly set the Text then the current value is // always replaced with one from the drop-down list when edit begins.) Text = _dataGridView.CurrentCell.Value as string; SelectAll();
处理 DataGridView
的 EditingControlShowing
事件,如 OhBeWise's回答相关问题以设置下拉项,如果需要,还可以设置自动完成模式:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox box = e.Control as ComboBox;
if (box != null)
{
box.AutoCompleteSource = AutoCompleteSource.ListItems;
box.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
box.DataSource = _dropDownItems;
}
}
如果您希望所有行都使用相同的下拉项,那么您始终可以将其设为 DropDownComboBoxColumn
的属性,例如 DropDownStyle
并在 PrepareEditingControlForEdit 中进行设置
以避免必须处理 EditingControlShowing
。
关于c# - 将接受任何文本的 DataGridView ComboBox 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41281920/