Can't edit Point[] or List at design ti

2020-04-08 11:54发布

I'm creating custom control that will draw shape from list (or array) of points. I have basic drawing functionality done, but now I'm struggling with design-time support in Visual Studio.

I've created two properties:

private Point _point;
public Point Point
{
    get { return _point; }
    set { _point = value; }
}

private Point[] _points;
public Point[] Points
{
    get { return _points; }
    set { _points = value; }
}

As seen on screen below Point is editable, but editor for Points isn't working. For each property I get error Object does not match target type.

enter image description here

If I change Point to MyPoint(custom class with X,Y properties) editor works just fine, but I don't want to create unneeded extra class because editor does not work when it should.

My question is: Can I use array or list of point as public property and have design-time support for it?

2条回答
家丑人穷心不美
2楼-- · 2020-04-08 12:29

If you can add a reference to PresentationCore and WindowsBase, you can utilize the System.Windows.Media.PointCollection

private System.Windows.Media.PointCollection _points = new System.Windows.Media.PointCollection();
public System.Windows.Media.PointCollection Points
{
    get { return _points; }
    set { _points = value; }
}

Hope that can help.

查看更多
来,给爷笑一个
3楼-- · 2020-04-08 12:34

You can create a custom collection editor deriving CollectionEditor and set typeof(List<Point>) as collection type, also register a new TypeConverterAttribute for Point:

// Add reference to System.Design
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.ComponentModel.Design;

public class MyPointCollectionEditor : CollectionEditor
{
    public MyPointCollectionEditor() : base(typeof(List<Point>)) { }
    public override object EditValue(ITypeDescriptorContext context,
        IServiceProvider provider, object value)
    {
        TypeDescriptor.AddAttributes(typeof(Point), 
            new Attribute[] { new TypeConverterAttribute() });
        var result = base.EditValue(context, provider, value);
        TypeDescriptor.AddAttributes(typeof(Point), 
            new Attribute[] { new TypeConverterAttribute(typeof(PointConverter)) });
        return result;
    }
}

Then it's enough to register it as editor of your List<Point>:

using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;

public class MyClass : Component
{
    public MyClass() { Points = new List<Point>(); }

    [Editor(typeof(MyPointCollectionEditor), typeof(UITypeEditor))]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public List<Point> Points { get; private set; }
}
查看更多
登录 后发表回答