Search code examples
c#winformsinheritanceuser-controlswindows-forms-designer

How to fix the errror 'The designer must create an instance of type " " but cant because it marked abstract"


I always get the error The designer must create an instance of type "BaseFractal" but cant because it marked abstract'. None of the solutions on How can I get Visual Studio 2008 Windows Forms designer to render a Form that implements an abstract base class? worked

Are there any other solutions for this error?

[System.ComponentModel.TypeDescriptionProvider 
(typeof(AbstractControlDescriptionProvider<BaseFractal, UserControl>))]
public abstract class BaseFractal : UserControl
{
    private Contour _Contour = new Contour() { color = Color.Black, weight = 1, indent = Indents.full };

    /// <summary>
    /// Sets or gets the contour fields
    /// </summary>
    /// <remarks>
    /// TODO
    /// </remarks>
    public Contour Contour
    {
        get { return _Contour; }
        set { _Contour = value; }
    }

    private int _Order = 0;

    /// <summary>
    /// Sets or gets the order of the fractal
    /// </summary>
    /// <remarks>
    /// TODO
    /// </remarks>
    public int Order
    {
        get { return _Order; }
        set { _Order = value; }
    }

    public BaseFractal()
    {
        InitializeComponent();
    }

    /// <summary>
    /// Create the path that needs to be drawn
    /// </summary>
    /// <remarks>
    /// TODO
    /// </remarks>
    protected abstract GraphicsPath CreatePath();

    /// <summary>
    /// Draw the fractals contour
    /// </summary>
    /// <remarks>
    /// TODO
    /// </remarks>
    protected void DrawFractal(PaintEventArgs e)
    {
        using (SolidBrush brush = new SolidBrush(Contour.color))
        {
            e.Graphics.FillPath(brush, CreatePath());
        }
    }

Solution

  • The designer doesn't have any problem in showing an abstract control in designer. The problem is when your control has an abstract base class.

    Let's say you have an abstract BaseControl as base class for MyControl. Then when you try to see BaseControl in designer, there is no problem, but the designer cannot show MyControl.

    The problem is because when you open MyControl in design view, the designer tries to create an instance of the base class to show it in the designer but since the base class is abstract it fails to create an instance and fails to load.

    As an option to solve the problem, you can create a non-abstract base class deriving from the base control for debug mode. Then the designer can show MyControl.

    Note: Using #if DEBUG is just to get rid of the intermediate non-abstract base when you build for RELEASE. If you don't care about it, you don't need these directives and you can just create the intermediate non abstract base and use it.

    namespace SampleWinApp
    {
    #if DEBUG
        public partial class MyControl : NonAbstractBase
    #else
        public partial class MyControl : BaseControl
    #endif
        {
            public MyControl()
            {
                InitializeComponent();
            }
        }
    #if DEBUG
        public class NonAbstractBase : BaseControl { }
    #endif
    }
    

    And here is my abstract BaseControl:

    namespace SampleWinApp
    {
        public abstract partial class BaseControl : UserControl
        {
            public BaseControl()
            {
                InitializeComponent();
            }
        }
    }