在 DataGridView 中设置的 DataGridViewComboBox,默认是不可编辑的,即使将其列属性 DisplayStyle 设置成 ComboBox 或其他,也无法编辑;
故作如下处理:
一 DataGridViewComboBoxCell
重写 DataGridViewComboBox 的单元控件 DataGridViewComboBoxCell

1 /// <summary>
2 /// 自定义可编辑下拉框单元
3 /// </summary>
4 public class DataGridViewComboEditBoxCell : DataGridViewComboBoxCell
5 {
6 public override void InitializeEditingControl(int rowIndex, object initialFormattedValue,
7 DataGridViewCellStyle dataGridViewCellStyle)
8 {
9 base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
10
11 ComboBox comboBox = (ComboBox)base.DataGridView.EditingControl;
12 if (comboBox != null)
13 {
14 comboBox.DropDownStyle = ComboBoxStyle.DropDown;
15 comboBox.AutoCompleteMode = AutoCompleteMode.Suggest;
16 comboBox.Validating += new CancelEventHandler(comboBox_Validating);
17 }
18 }
19
20 protected override object GetFormattedValue(object value, int rowIndex,
21 ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter,
22 TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
23 {
24 if (value != null && value.ToString().Trim() != string.Empty)
25 {
26 if (Items.IndexOf(value) == -1)// 如果下拉框中不存在填入的值,则添加到下拉框中
27 {
28 Items.Add(value);
29 // 添加到该列所有单元所绑定的下拉列表中
30 DataGridViewComboBoxColumn col = (DataGridViewComboBoxColumn)OwningColumn;
31 col.Items.Add(value);
32 }
33 }
34
35 return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
36 }
37
38 private void comboBox_Validating(object sender, CancelEventArgs e)
39 {
40 DataGridViewComboBoxEditingControl cbo = (DataGridViewComboBoxEditingControl)sender;
41 if (cbo.Text.Trim() == string.Empty)
42 return;
43
44 DataGridView grid = cbo.EditingControlDataGridView;
45 object value = cbo.Text;
46
47 if (cbo.Items.IndexOf(value) == -1)
48 {
49 DataGridViewComboBoxColumn cboCol = (DataGridViewComboBoxColumn)grid.Columns[grid.CurrentCell.ColumnIndex];
50 // 添加到当前下拉框中以及模版中,避免出现重复项
51 cbo.Items.Add(value);
52 cboCol.Items.Add(value);
53 grid.CurrentCell.Value = value;
54 }
55 }
56 }
1、GetFormattedValue 方法
获取单元格数据的格式化值。
protected override Object GetFormattedValue( Object value,// 要格式化的值 int rowIndex,// 该单元格父行的索引 ref DataGridViewCellStyle cellStyle,// 对单元格有效样式 TypeConverter valueTypeConverter,// 与值类型关联的类型转换器,提供到格式化值类型的自定义转换 TypeConverter formattedValueTypeConverter,// 与格式化值类型相关联的类型转换期,提供从该值类型进行的自定义转换 DataGridViewDataErrorContexts context// 用于描述需要格式化的上下文 ) 返回值:应用了格式设置之后单元格数据的值
2、InitializeEditingControl 方法
附加并初始化寄宿的编辑控件。
public override void InitializeEditingControl(
int rowIndex,// 该单元格父行的索引
Object initialFormattedValue,// 要在控件中显示的初始值
DataGridViewCellStyle dataGridViewCellStyle// 寄宿控件的单元格样式
)
该方法主要操作设置宿主 ComboBox 控件的可视化属性(MaxDropDownItems, DropDownWidth, FlatStyle)、设置宿主 ComboBox 控件的数据绑定属性(DataSource, DisplayMember, ValueMember)、重新初始化宿主 ComboBox 控件的 Items 属性;
二 DataGridViewComboBoxColumn
重写 DataGridViewComboBox 的列控件 DataGridViewComboBoxColumn,并设置其单元模版为上面自定义的单元

1 public class DataGridViewComboEditBoxColumn : DataGridViewComboBoxColumn
2 {
3 public DataGridViewComboEditBoxColumn()
4 {
5 DataGridViewComboEditBoxCell obj = new DataGridViewComboEditBoxCell();
6 this.CellTemplate = obj;
7 }
8 }
9
三 应用自定义可编辑的 DataGridViewComboEditBoxColumn
将 DataGridViewComboEditBoxColumn 的命名空间添加到相应的 Form 中,然后在 DataGridView 的 Columns 属性中对列进行编辑时,即可看到自定义的 DataGridViewComboEditBoxColumn 控件,如下图:
注:如果是在同一个项目里添加了一、二的两个类后,需要先编译一下,方可在 DataGridView 的列编辑时看到该自定义 ComboEditBoxColumn。
则可以达到如下效果
四 参考资料
1、http://hi.baidu.com/guog_/item/13003e933738321f924f4157
2、GetFormattedValue:https://msdn.microsoft.com/zh-cn/library/ms158982(v=vs.90).aspx
3、InitializeEditingControl:http://msdn.microsoft.com/zh-tw/beginner/system.windows.forms.datagridviewcomboboxcell.initializeeditingcontrol(zh-cn,VS.100).aspx
4、参考 Demo:https://github.com/Memento1990/demo.net/tree/master/cnblog/EditableDataGridViewComboBox
来源:https://www.cnblogs.com/memento/p/4319995.html



