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

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

有谁能解释为什么会出现这种差异?

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

System.ComponentModel.Design.CollectionEditor .CollectionEditorCollectionForm.SelectionWrapperSystem.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor)实现只返回this

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

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

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

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

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

我怀疑PointConverter因为PointF类没有TypeConverterAttribute ,它工作正常。

在下面的示例中,我使用MSDN中的一些代码拼凑在一起,在集合中使用Point类时会出现问题,而在使用自定义TypeConverterMyPoint类时则会出现问题。

 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 points; private List pointfs; private List mypoints; public List PointList { get{ return points;} set{ points = value;} } public List PointFList { get {return pointfs;} set{pointfs = value;} } public List MyPointList { get { return mypoints; } set { mypoints = value; } } public UserControl1() { InitializeComponent(); } } } 

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