编辑时,DataGridView单元格中的自定义控件引发FormatException [英] Custom Control in DataGridView Cell Throws FormatException When Editing

查看:50
本文介绍了编辑时,DataGridView单元格中的自定义控件引发FormatException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个自定义控件来编辑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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆