DataGridViewComboBoxColumn 绑定对象集合时存在BUG?

     DataGridview 绑定的是对象集合,里面有一列是下拉列表,也用集合绑定,一切看上去很美好,可是当我改变选择下拉列表时,却发生BUG。字符串不能转成对象!不知是DataGridview里的对应的下拉列表列保存的是字符串,还是下拉列表保存的是字符串。
    

   查google 得知,下拉列表是以模板的方式进行编辑,这有点以前web      下的datagrid

(既然编辑的时候用另一种控件,为何显视时不直接使用label算了,就象Infragistics UltraGrid)。于是创建一下模板列继承DataGridViewComboBoxCell。果然有ParseFormattedValue这个方法。跟踪,原来formattedValue传进来时是一个字符串类型。看来问题很容易解决吗,于是转成对象:

  public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
        
{
              ComboBox comboBox 
= base.DataGridView.EditingControl as ComboBox;
              formattedValue 
= (BizObject)comboBox.SelectedItem;
            
return base.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
        }


这下好了,出现了新的问题

类型转化错误!由于调用了内部类,这下子跟踪不了了,反编译System.Windows.Forms,得到下面方法:

public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
{
      
if (valueTypeConverter == null)
      
{
            
if (this.ValueMemberProperty != null)
            
{
                  valueTypeConverter 
= this.ValueMemberProperty.Converter;
            }

            
else if (this.DisplayMemberProperty != null)
            
{
                  valueTypeConverter 
= this.DisplayMemberProperty.Converter;
            }

      }

      
if (((this.DataManager != null&& ((this.DisplayMemberProperty != null|| (this.ValueMemberProperty != null))) || (!string.IsNullOrEmpty(this.DisplayMember) || !string.IsNullOrEmpty(this.ValueMember)))
      
{
            
object obj1 = base.ParseFormattedValueInternal(this.DisplayType, formattedValue, cellStyle, formattedValueTypeConverter, this.DisplayTypeConverter);
            
object obj2 = obj1;
            
if (!this.LookupValue(obj2, out obj1))
            
{
                  
if (obj2 != DBNull.Value)
                  
{
                        
throw new FormatException(string.Format(CultureInfo.CurrentCulture, SR.GetString("Formatter_CantConvert"), new object[] { obj1, this.DisplayType }));
                  }

                  
return DBNull.Value;
            }

            
return obj1;
      }

      
return base.ParseFormattedValueInternal(this.ValueType, formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
}


internal object ParseFormattedValueInternal(Type valueType, object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
{
      
if (cellStyle == null)
      
{
            
throw new ArgumentNullException("cellStyle");
      }

      
if (this.FormattedValueType == null)
      
{
            
throw new FormatException(SR.GetString("DataGridViewCell_FormattedValueTypeNull"));
      }

      
if (valueType == null)
      
{
            
throw new FormatException(SR.GetString("DataGridViewCell_ValueTypeNull"));
      }

      
if ((formattedValue == null|| !this.FormattedValueType.IsAssignableFrom(formattedValue.GetType()))
      
{
            
throw new ArgumentException(SR.GetString("DataGridViewCell_FormattedValueHasWrongType"), "formattedValue");
      }

      
return Formatter.ParseObject(formattedValue, valueType, this.FormattedValueType, (valueTypeConverter == null? this.ValueTypeConverter : valueTypeConverter, (formattedValueTypeConverter == null? this.FormattedValueTypeConverter : formattedValueTypeConverter, cellStyle.FormatProvider, cellStyle.NullValue, cellStyle.IsDataSourceNullValueDefault ? Formatter.GetDefaultDataSourceNullValue(valueType) : cellStyle.DataSourceNullValue);
}

 

在方法ParseFormattedValueInternal 里有一个属性:  this.FormattedValueType 是字符串型,而我传进去的已经变成了对象型了,所以在这里报错了。

 

属性 FormattedValueType覆盖了基类, 这里已经变成了字符串类型

public override Type FormattedValueType
{
      
get
      {
            
return DataGridViewComboBoxCell.defaultFormattedValueType;
      }
}
这个defaultFormattedValueType值就不知从哪里设来的了。 然而基类 FormattedValueType类里的this.ValueType而反是我需要的对象的类型。
[Browsable(false)]
public virtual Type FormattedValueType
{
      
get
      {
            
return this.ValueType;
      }
}

于是用这个基类 FormattedValueType重新覆盖。结果错误是没有了,可下拉列表列全是空白。不过我点击下拉列表,却是程序需要的选择。看来显示又出现了问题.

 

最后的解决方法是:BizObject 是我对象的基类

  public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
        {
            ComboBox comboBox 
= base.DataGridView.EditingControl as ComboBox;
            formattedValue 
= (BizObject)comboBox.SelectedItem;
            
return formattedValue;

        }

虽然没有问题了,但是直接反回而忽略其它几个参数,感觉不是很自然。不知大家有没有更好的方法。

posted @ 2006-08-28 10:51  瑞德船长  阅读(4166)  评论(3编辑  收藏  举报