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.SelectionWrapper
的System.ComponentModel.ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor)
实现只返回this
。
根据上述ICustomTypeDescriptor
接口方法的MSDN页面,实现应该如此
返回包含指定属性描述符描述的属性的对象。
如果我理解正确,在这种情况下,实现与文档相矛盾。
这是基于我自己的一些研究,所以不要把它视为理所当然。 我在Microsoft Connect上发布了此问题的报告,所以希望我们几天后就能确定。 我会在收到答复时报告。
我不是.NET / C#专家,但问题似乎出现在PointConverter
类中,它被用作System.Drawing.Point
类的TypeConverterAttribute
。 集合编辑器必须使用失败的PointConverter
类中的某些内容。
我怀疑PointConverter
因为PointF
类没有TypeConverterAttribute
,它工作正常。
在下面的示例中,我使用MSDN中的一些代码拼凑在一起,在集合中使用Point
类时会出现问题,而在使用自定义TypeConverter
的MyPoint
类时则会出现问题。
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设置为默认值。