views:

51

answers:

0

I have the following point class definition along with its type converter, and ...

[TypeConverterAttribute(typeof(MyPointConverter))]
public class MyPoint
{
    public MyPoint(double x, double y)
    {
        X = x;
        Y = y;
    }

    public MyPoint()
    {
    }

    public double X { get; set; }
    public double Y { get; set; }

}
internal class MyPointConverter : ExpandableObjectConverter
{

    // Don't need to override CanConvertTo if converting to string, as that's what base TypeConverter does
    // Do need to override CanConvertFrom since it's base converts from InstanceDescriptor
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        // We can be converted to a string or an InstanceDescriptor
        if (destinationType == typeof(string))
            return true;
        if (destinationType == typeof(InstanceDescriptor))
            return true;
        return base.CanConvertTo(context, destinationType);
    }

    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        // We can convert from a string to a Point2D type
        if (sourceType == typeof(string)) 

           return true; 

        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo info, object value)
    {

        // If converting from a string
        if (value is string)
        {
            // Build a MyPoint type
            try
            {
                // Get MyPoint properties
                string propertyList = (string)value;

                string[] properties = propertyList.Split(',');

                return new MyPoint(double.Parse(properties[0]),
                                    double.Parse(properties[1]));
            }
            catch
            {
                throw new ArgumentException("Invalid arguments.");
            }

        }
        return base.ConvertFrom(context, info, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {

        // Convert to string
        if ((destinationType == typeof (string)))
        {

            MyPoint pt = (MyPoint) value;

            return string.Format("{0}, {1}", pt.X, pt.Y);

        }

        // Convert to InstanceDescriptor
        if ((destinationType == typeof (InstanceDescriptor)))
        {

            MyPoint pt = (MyPoint) value;

            object[] properties = new object[2];
            Type[] types = new Type[2];

            // Color
            types[0] = typeof (double);
            properties[0] = pt.X;

            // Width
            types[1] = typeof (double);
            properties[1] = pt.Y;

            // Build constructor
            ConstructorInfo ci = typeof (MyPoint).GetConstructor(types);
            return new InstanceDescriptor(ci, properties);
        }


        // Base ConvertTo if neither string or InstanceDescriptor required
        return base.ConvertTo(context, culture, value, destinationType);

    }

    public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
    {
        // Use the dictionary to create a new instance
        return new MyPoint((double)propertyValues["X"], (double)propertyValues["Y"]);
    }
}

The following declarations in the Form1 class:

 MyPoint mp = new MyPoint(0,0);

    public MyPoint MP
    {
        get { return mp; }
        set { mp = value; }
    }

    List<MyPoint> myList = new List<MyPoint>();

    public List<MyPoint> MyList
    {
        get { return myList; }
        set { myList = value; }
    }

I can change MP in the PropertyGrid (expanding it) and inside the CollectionEditor but I CAN'T change the values of MP simply editing the text in the same row (without expanding) and pressing ENTER. Why?

Thanks!