[Winform] DataGridView 中 DataGridViewComboBox 的可编辑

在 DataGridView 中设置的 DataGridViewComboBox,默认是不可编辑的,即使将其列属性 DisplayStyle 设置成 ComboBox 或其他,也无法编辑;

image

故作如下处理:

一  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 }
DataGridViewComboEditBoxCell

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

将 DataGridViewComboEditBoxColumn 的命名空间添加到相应的 Form 中,然后在 DataGridView 的 Columns 属性中对列进行编辑时,即可看到自定义的 DataGridViewComboEditBoxColumn 控件,如下图:

image

注:如果是在同一个项目里添加了一、二的两个类后,需要先编译一下,方可在 DataGridView 的列编辑时看到该自定义 ComboEditBoxColumn。

则可以达到如下效果

image,在单元中编辑的项,均可在下拉框中找到记录;

四  参考资料

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

posted @ 2015-03-07 11:23  01码匠  阅读(7713)  评论(0编辑  收藏  举报