4

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?

Community
  • 1
  • 1
Misiu
  • 4,738
  • 21
  • 94
  • 198
  • The problem might be the collection editor confusing `point` for `pointf` http://stackoverflow.com/questions/2597737/collectioneditor-yielding-object-does-not-match-target-type-for-system-drawin – Timothy Groote Jul 25 '16 at 06:51
  • @TimothyGroote thanks for link – Misiu Jul 25 '16 at 06:54

2 Answers2

2

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.

txtechhelp
  • 6,625
  • 1
  • 30
  • 39
  • Thanks for suggestion, I'll leave this question open for some time. Your solution is an option, but requires two dependencies. I'd like to keep them as minimum as possible, so maybe there will be an option to use Point instead Points but using build in collections – Misiu Jul 25 '16 at 07:48
  • @Misiu, no worries on leaving it open, I'd be curious if there's another way that doesn't involve a custom class or custom container as well. But out of curiosity, what version of the .NET framework are you targeting? `PresentationCore` and `WindowsBase` are part of the .NET framework since 3.0, so adding a reference to them isn't adding a dependency like adding a reference to the `XNA` framework would be .. ? – txtechhelp Jul 25 '16 at 08:47
2

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; }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • Thank You. This works fine. I have problem with `Designer.cs` file. After adding points they are visible in `Designer.cs` as `this.shape1.Points.Add(((System.Drawing.Point)(resources.GetObject("shape1.Points"))));` Can I change this, so that instead of resources I'll see values in Designer? Do I must create some sort of converter for it? – Misiu Jul 26 '16 at 06:31
  • After closing the dialog (after `EditValue`) set the converter to `PointConverter` again. I edited the post. – Reza Aghaei Jul 26 '16 at 11:31
  • Fantastic! Thank You for help. – Misiu Jul 26 '16 at 11:36