在 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