在 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