我有一个自定义控件,其Value
属性是一个对象。该控件还具有Text
属性,该属性根据对象显示对象的字符串属性。
此自定义控件托管在DataGridView
中,我实现了所需的接口IDataGridViewEditingControl
以使其正常工作。我还有2个继承自DataGridViewColumn
和DataGridViewTextBoxCell
的课程。
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属性中有对象。
答案 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正常工作。