.NetFramework 2.0里提供的DataGridViewComboBoxColumn 只有在以下情况下才正常工作:它的所有单元格值(由 DataGridView.DataSource 属性填充)与选择的范围(由 DataSource 属性或 Items 属性填充)之间存在映射。如果此映射不存在,则当该列位于视图中时,会出现消息“进行格式设置时出现错误,显示”。因此,这个ComboBox无法进行自由编辑,我写了个扩展的 DataGridViewComboEditBoxColumn 类实现了ComboBoxStyle.DropDown的功能,代码的关键点为两处,一是在显示时将ComboBoxColumn以及ComboBox的Items添加入所有可能出现的项,在GetFormattedValue时实现,二是在编辑验证ComboBox数据时即时插入新项,在ComboBox.Validating时实现。
    public class DataGridViewComboEditBoxCell : DataGridViewComboBoxCell
    
{
        
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        
{
            
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
           
            ComboBox comboBox 
= base.DataGridView.EditingControl as ComboBox;
            
if (comboBox != null)
            
{
                comboBox.DropDownStyle 
= ComboBoxStyle.DropDown;
                comboBox.Validating 
+= new CancelEventHandler(comboBox_Validating);
            }

        }


        
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
        
{
            
if (value != null)
            
{
                
if (value.ToString().Trim() != string.Empty)
                
{
                    
if (Items.IndexOf(value) == -1)
                    
{
                        Items.Add(value);
                        DataGridViewComboBoxColumn col 
= OwningColumn as DataGridViewComboBoxColumn;
                        col.Items.Add(value);
                    }

                }

            }

            
return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
        }


        
void comboBox_Validating(object sender, System.ComponentModel.CancelEventArgs e)
        
{
            DataGridViewComboBoxEditingControl cbo 
= sender as DataGridViewComboBoxEditingControl;
            
if (cbo.Text.Trim() == string.Empty) return;

            DataGridView grid 
= cbo.EditingControlDataGridView;
            
object value = cbo.Text;
            
// Add value to list if not there
            
            
if (cbo.Items.IndexOf(value) == -1)
            
{
                DataGridViewComboBoxColumn cboCol 
= grid.Columns[grid.CurrentCell.ColumnIndex] as DataGridViewComboBoxColumn;
                
// Must add to both the current combobox as well as the template, to avoid duplicate entries
                cbo.Items.Add(value);
                cboCol.Items.Add(value);
                grid.CurrentCell.Value 
= value;
            }

        }

    }


    
public class DataGridViewComboEditBoxColumn : DataGridViewComboBoxColumn
    
{
        
public DataGridViewComboEditBoxColumn()
        
{
            DataGridViewComboEditBoxCell obj 
= new DataGridViewComboEditBoxCell();
            
this.CellTemplate = obj;
        }

    }

posted on 2006-07-14 16:41  愚公  阅读(6203)  评论(2编辑  收藏  举报