CollectionEditor产生“对象与目标类型不匹配”。 for System.Drawing.Point

时间:2010-04-08 05:19:31

标签: c# collectioneditor

我有一个自定义控件,其属性类型为Collection<System.Drawing.Point>。当我使用CollectionEditor编辑此属性时,CollectionEditor窗口会显示"Object does not match target type.""X"属性的"Y"。但是如果我使用System.Drawing.PointF代替,那就没有失败。

有人可以解释为什么会出现这种差异吗?

3 个答案:

答案 0 :(得分:3)

Point和PointF之间的区别确实在于PointConverter。为什么这会导致问题是一个相当长的故事,但在一天结束时归结为以下几点:

System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor)中的System.ComponentModel.Design.CollectionEditor .CollectionEditorCollectionForm.SelectionWrapper实施只返回this

根据上述ICustomTypeDescriptor接口方法的MSDN页面,实现应该

  

返回包含指定属性描述符描述的属性的对象。

如果我理解正确,在这种情况下,实现与文档相矛盾。

这是基于我自己的一些研究,所以不要把它视为理所当然。我在Microsoft Connect上发布了此问题的报告,所以希望我们在几天内就能确定。我会在收到答复时报告。

答案 1 :(得分:2)

我不是.NET / C#专家,但问题似乎在PointConverter类中的某个位置,该类用作TypeConverterAttribute类的System.Drawing.Point。集合编辑器必须使用失败的PointConverter类中的某些内容。

我怀疑PointConverter因为PointF类没有TypeConverterAttribute,所以它运行正常。

在下面的例子中,我使用MSDN中的一些代码拼凑在一起,在集合中使用Point类时会出现问题,但在MyPoint类中没有正在使用自定义TypeConverter

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;

namespace WindowsControlLibrary1
{
    public class MyTypeConverter : TypeConverter
    {
        // Overrides the CanConvertFrom method of TypeConverter.
        // The ITypeDescriptorContext interface provides the context for the
        // conversion. Typically, this interface is used at design time to 
        // provide information about the design-time container.
        public override bool CanConvertFrom(ITypeDescriptorContext context,
           Type sourceType)
        {

            if (sourceType == typeof(string))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
        // Overrides the ConvertFrom method of TypeConverter.
        public override object ConvertFrom(ITypeDescriptorContext context,
           CultureInfo culture, object value)
        {
            if (value is string)
            {
                string[] v = ((string)value).Split(new char[] { ',' });
                return new MyPoint(int.Parse(v[0]), int.Parse(v[1]));
            }
            return base.ConvertFrom(context, culture, value);
        }
        // Overrides the ConvertTo method of TypeConverter.
        public override object ConvertTo(ITypeDescriptorContext context,
           CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                return ((MyPoint)value).X + "," + ((MyPoint)value).Y;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

    [SerializableAttribute]
    [TypeConverterAttribute(typeof(MyTypeConverter))]
    public struct MyPoint
    {
        private int x;
        private int y;

        public MyPoint(int _x, int _y)
        {
            x = _x;
            y = _y;
        }

        public int X
        {
            get { return x; }
            set { x = value; }
        }
        public int Y
        {
            get { return y; }
            set { y = value; }
        }

    }

    public partial class UserControl1 : UserControl
    {
        private List<System.Drawing.Point> points;
        private List<System.Drawing.PointF> pointfs;
        private List<MyPoint> mypoints;


        public List<System.Drawing.Point> PointList
        {
            get{ return points;}
            set{ points = value;}
        }

        public List<System.Drawing.PointF> PointFList
        {
            get {return pointfs;}
            set{pointfs = value;}
        }

        public List<MyPoint> MyPointList
        {
            get { return mypoints; }
            set { mypoints = value; }
        }

        public UserControl1()
        {
            InitializeComponent();
        }
    }
}

答案 2 :(得分:0)

我的解决方案是在使用collectioneditor编辑列表(点数)之前,使用TypeDescriptor.AddAttributes(GetType(Drawing.Point), New TypeConverterAttribute())将Point的typeconverter设置为空,然后使用TypeDescriptor.AddAttributes(GetType(Drawing.Point), New TypeConverterAttribute(GetType(PointConverter)))将typeconverter设置为默认值。