DataGridView试图从字符串转换为对象

时间:2015-03-27 11:52:56

标签: c# visual-studio visual-studio-2012

我有一个自定义控件,其Value属性是一个对象。该控件还具有Text属性,该属性根据对象显示对象的字符串属性。

此自定义控件托管在DataGridView中,我实现了所需的接口IDataGridViewEditingControl以使其正常工作。我还有2个继承自DataGridViewColumnDataGridViewTextBoxCell的课程。

CustomerTypeDto类:

public class CustomerTypeDto
{
    public int Id {get; set;}
    public int Description {get; set}
    //Other properties...
}

剩下的一个问题是,在我从控件中选择一个值并且DataGridView尝试结束单元格编辑后,我得到以下异常:

  

System.FormatException:来自' System.String'的无效演员表到' CustomerTypeDto'。 ---> System.InvalidCastException:来自&SystemString'的无效演员表。到' CustomerTypeDto'。      在System.Convert.DefaultToType(IConvertible值,类型targetType,IFormatProvider提供程序)      在System.String.System.IConvertible.ToType(Type type,IFormatProvider provider)      at System.Convert.ChangeType(Object value,Type conversionType,IFormatProvider provider)      在System.Windows.Forms.Formatter.ChangeType(对象值,类型类型,IFormatProvider formatInfo)      ---内部异常堆栈跟踪结束---      在System.Windows.Forms.Formatter.ChangeType(对象值,类型类型,IFormatProvider formatInfo)      at System.Windows.Forms.Formatter.ParseObjectInternal(Object value,Type targetType,Type sourceType,TypeConverter targetConverter,TypeConverter sourceConverter,IFormatProvider formatInfo,Object formattedNullValue)      在System.Windows.Forms.Formatter.ParseObject(Object value,Type targetType,Type sourceType,TypeConverter targetConverter,TypeConverter sourceConverter,IFormatProvider formatInfo,Object formattedNullValue,Object dataSourceNullValue)      在System.Windows.Forms.DataGridViewCell.ParseFormattedValueInternal(Type valueType,Object formattedValue,DataGridViewCellStyle cellStyle,TypeConverter formattedValueTypeConverter,TypeConverter valueTypeConverter)      在System.Windows.Forms.DataGridViewCell.ParseFormattedValue(Object formattedValue,DataGridViewCellStyle cellStyle,TypeConverter formattedValueTypeConverter,TypeConverter valueTypeConverter)      在System.Windows.Forms.DataGridView.PushFormattedValue(DataGridViewCell& dataGridViewCurrentCell,Object formattedValue,Exception& exception)

我需要覆盖哪个方法或属性,以便DataGridView可以从我的对象转换为字符串,反之亦然。

我应该直接从DataGridViewTextBoxCell还是从DataGridViewCell继承?

修改

这是我的手机课程:

public class CustomerTypeCell : DataGridViewTextBoxCell
{
    public CustomerTypeCell()
        : base()
    { }

    public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);

        CustomControl ctl = DataGridView.EditingControl as CustomControl;

        if (this.Value == null)
            ctl.Value = (CustomerTypeDto)this.DefaultNewRowValue;
        else
            ctl.Value = (CustomerTypeDto)this.Value;
    }

    public override Type EditType
    {
        get { return typeof(CustomControl); }
    }

    public override Type ValueType
    {
        get { return typeof(CustomerTypeDto); }
    }

    public override object DefaultNewRowValue
    {
        get { return null; }
    }

    public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
    {
        return base.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
    }
}

FormattedValueType中的属性DataGridViewTextBoxCell始终返回字符串。

在上面的方法ParseFormattedValue中,它试图从字符串转换为我的对象。这种方法的描述:

  

将为显示格式化的值转换为实际的单元格值。

但这没有意义,因为Value的类型为CustomerTypeDto,那么这种解析如何发挥作用呢?

基本上我要做的就是让用户从我的自定义控件中选择一个CustomerType对象。此对象应为单元格的值,并且值的文本(在本例中为Description属性)在单元格中显示为字符串。

我不明白为什么DataGridView想要解析对象中的字符串,如果我已经在单元格的value属性中有对象。

3 个答案:

答案 0 :(得分:1)

您的CustomerTypeDto类需要一个字符串类型的显式强制转换运算符。

class CustomerTypeDto
{
    // string -> CustomerTypeDto
    public static explicit operator CustomerTypeDto(string s)
    {
        CustomerTypeDto ctd = new CustomerTypeDto();
        // ... do something with the string.
        return ctd;
    }
    // CustomerTypeDto -> string
    public static explicit operator String(CustomerTypeDto ctd)
    {
        return ctd.toString();
        // or some other way to return it's string value.
    }
    // other stuff...
}

所以你可以这样做:

return (CustomerTypeDto)someString;

答案 1 :(得分:0)

如果您想提前实现自己的价值, 实施到e.ParsingApplied = true;后,使用方法e.Value = (ObjOfYourType) 我已在删除异常之前引起的事件CellParsing中使用了它。

答案 2 :(得分:0)

此问题已通过2种可行的解决方案得到了解答 Custom Control in DataGridView Cell Throws FormatException When Editing

第一个答案https://stackoverflow.com/a/36656360仅适用于我的评论,因此完整的解决方案是

public object GetEditingControlFormattedValue (DataGridViewDataErrorContexts context)
{
  if ((context & DataGridViewDataErrorContexts.Parsing) != 0)
  {
    // Here you should not return string, but your value
    return Value;
  }
  return EditingControlFormattedValue;
}

public override object ParseFormattedValue (object formattedValue,
                                            DataGridViewCellStyle cellStyle,
                                            TypeConverter formattedValueTypeConverter,
                                            TypeConverter valueTypeConverter)
{
  if (formattedValue is CustomerTypeDto)
  {
    return formattedValue;
  }
  return base.ParseFormattedValue (formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
}

第二个答案 https://stackoverflow.com/a/36668621正常工作。