编辑时,DataGridView单元格中的自定义控件引发FormatException [英] Custom Control in DataGridView Cell Throws FormatException When Editing
问题描述
我创建了一个自定义控件来编辑DataGridView单元中的自定义值.我在这里跟随示例:如何:Windows窗体DataGridView单元中的主机控件
I have created a custom control to edit a custom value in a DataGridView cell. I am following the example here: How to: Host Controls in Windows Forms DataGridView Cells
我有一个自定义数据类,它是绑定到DataGridView的对象列表的成员.
I have a custom data class that is a member of a list of objects bound to the DataGridView.
internal class CustomValue
{
// Some stuff is here.
}
我创建了一个自定义控件来编辑实现IDataGridViewEditingControl接口的单元格中的值.
I have created a custom control to edit the value in the cell that implements the IDataGridViewEditingControl interface.
internal partial class CustomValueEditControl : UserControl, IDataGridViewEditingControl
{
DataGridView m_dataGridView;
private bool m_valueChanged = false;
int m_rowIndex;
private CustomValue m_value;
public CustomValue Value
{
get
{
return m_value;
}
set
{
m_value = value;
}
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
}
public DataGridView EditingControlDataGridView
{
get
{
return m_dataGridView;
}
set
{
m_dataGridView = value;
}
}
public object EditingControlFormattedValue
{
get
{
return this.Value.ToString();
}
set
{
if (value is String)
{
CustomValue val;
if (CustomValue.TryParse((String)value, out val))
{
this.Value = val;
}
else
{
this.Value = new CustomValue();
}
}
}
}
public int EditingControlRowIndex
{
get
{
return m_rowIndex;
}
set
{
m_rowIndex = value;
}
}
public bool EditingControlValueChanged
{
get
{
return m_valueChanged;
}
set
{
m_valueChanged = value;
}
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & Keys.KeyCode)
{
case Keys.Up:
case Keys.Down:
return true;
default:
return !dataGridViewWantsInputKey;
}
}
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}
}
我已经建立了一个自DataGridViewTextBoxCell继承的自定义DataGridViewCell,因此该单元格仅显示自定义值的字符串表示形式,直到对其进行编辑.
I have set up a custom DataGridViewCell that descends from DataGridViewTextBoxCell so the cell just displays a string representation of the custom value until it is edited.
internal class CustomValueCell : DataGridViewTextBoxCell
{
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
CustomValueEditControl customValueEditControl = DataGridView.EditingControl as CustomValueEditControl;
if (this.Value == null)
{
customValueEditControl.Value = (CustomValue)this.DefaultNewRowValue;
}
else
{
customValueEditControl.Value = (CustomValue)this.Value;
}
}
public override Type EditType
{
get
{
return typeof(CustomValueEditControl);
}
}
public override Type ValueType
{
get
{
return typeof(CustomValue);
}
}
public override Type FormattedValueType
{
get
{
return typeof(string);
}
}
public override object DefaultNewRowValue
{
get
{
return new CustomValue();
}
}
}
我创建了一个自定义DataGridViewColumn.
I have created a custom DataGridViewColumn.
internal class CustomValueColumn : DataGridViewColumn
{
public CustomValueColumn()
: base(new CustomValueCell())
{
}
public override object Clone()
{
CustomValueColumn clone = (CustomValueColumn)base.Clone();
return clone;
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a CustomValueCell.
if (value != null && !value.GetType().IsAssignableFrom(typeof(CustomValueCell)))
{
throw new InvalidCastException("Must be a CustomValueCell");
}
base.CellTemplate = value;
}
}
}
该单元格正确显示了自定义类型的值,我可以使用自定义控件来编辑该值.当我离开编辑单元格时,我得到一个System.FormatException:在System.Convert.DefaultToType(IConvertable值,类型targetType,IFormatProvider提供程序)上从'System.String'到'CustomValue'的无效转换.
The cell shows the value of the custom type correctly, and I can use the custom control to edit the value. When I leave the editing cell, I get a System.FormatException: Invalid cast from 'System.String' to 'CustomValue' at System.Convert.DefaultToType(IConvertable value, Type targetType, IFormatProvider provider)...
在什么时候尝试将字符串强制转换为我的自定义值?CustomValueEditControl.GetEditingControlFormattedValue是否应该处理此问题?
At what point is it trying to cast a string to my custom value? Should this not be handled by the CustomValueEditControl.GetEditingControlFormattedValue?
推荐答案
所以我最终通过实现TypeConverter类解决了这个问题.
So I ended up solving this by implementing a TypeConverter class.
internal class CustomValueTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
CustomValue customValue;
if (CustomValue.TryParse((string)value, out customValue))
{
return customValue;
}
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
value.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
然后我必须用TypeConverterAttribute装饰CustomValue类.
Then I had to decorate the CustomValue class with a TypeConverterAttribute.
[TypeConverter(typeof(CustomValueTypeConverter))]
internal class CustomValue
{
// Some stuff here.
}
这篇关于编辑时,DataGridView单元格中的自定义控件引发FormatException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!