2010-04-08 1 views
8

Collection<System.Drawing.Point> 속성을 가진 사용자 지정 컨트롤이 있습니다. CollectionEditor을 사용하여이 속성을 편집 할 경우 CollectionEditor 창에 "X""Y" 속성에 대해 "Object does not match target type."이 표시됩니다. 하지만 System.Drawing.PointF을 대신 사용하면 실패하지 않습니다."개체가 대상 유형과 일치하지 않습니다." System.Drawing.Point에 대한

누구든지이 차이가 발생하는 이유를 설명해주십시오.

답변

3

Point와 PointF의 차이점은 실제로 PointConverter에 있습니다. 왜 이런 문제가 발생했는지는 꽤 긴 이야기이지만, 결국 다음과 같이 요약됩니다.

System.ComponentModel.Design.CollectionEditor .CollectionEditorCollectionForm.SelectionWrapper의 구현은 단순히 this을 반환합니다. ICustomTypeDescriptor 인터페이스의 상기 방법의 MSDN 페이지에 따르면

, 구현해야

복귀은 지정된 속성 기술자에 의해 기술 된 속성을 포함하는 개체.

정확하게 이해하면이 경우 구현이 설명서와 모순됩니다.

이것은 내 연구에 기반하고 있으므로 당연한 것으로 생각하지 마십시오. 이 문제에 대한 보고서를 Microsoft Connect에 게시 했으므로 앞으로 며칠 이내에 잘 알게 될 것입니다. 답변을 받으면 다시보고하겠습니다.

2

저는 .NET/C# expert는 아니지만 System.Drawing.Point 클래스의 TypeConverterAttribute으로 사용되는 PointConverter 클래스의 어딘가에있는 것으로 보입니다. 컬렉션 편집기는 실패한 PointConverter 클래스 내의 무언가를 사용해야합니다.

PointF 클래스에 TypeConverterAttribute이 없으므로 PointConverter으로 의심됩니다. 제대로 작동합니다. 모음에 Point 클래스를 사용할 때이 MSDN에서 몇 가지 코드를 사용하여 함께 자갈길 다음 예에서

는 문제가 아니라 사용자 정의 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<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(); 
     } 
    } 
} 
+0

감사합니다. bde. TypeConverter.GetCreateInstanceSupported()를 true로 설정하면됩니다. – smwikipedia

+0

true를 반환하는 GetCreateInstance()는 실제로 유형이 변경되지 않는다는 것을 의미합니다. 또는 적어도 하나의 속성이 읽기 전용이므로 즉, 속성을 수정하려는 경우 새 인스턴스를 만들어야합니다. 불행히도 이것은 항상 피할 수 없다는 것을 의미합니다. – kicsit

0

내 해결 방법은 콜렉션 편집자를 사용하여 포인트의 목록을 편집하기 전에 TypeDescriptor.AddAttributes(GetType(Drawing.Point), New TypeConverterAttribute())을 사용하여 Point의 typeconverter를 nothing으로 설정 한 다음 TypeDescriptor.AddAttributes(GetType(Drawing.Point), New TypeConverterAttribute(GetType(PointConverter)))을 사용하여 typeconverter를 기본값으로 설정하십시오.