如何修复错误“设计者必须创建类型为“”的实例,但不能因为它标记为抽象”

Posted

技术标签:

【中文标题】如何修复错误“设计者必须创建类型为“”的实例,但不能因为它标记为抽象”【英文标题】:How to fix the errror 'The designer must create an instance of type " " but cant because it marked abstract" 【发布时间】:2019-04-27 12:55:21 【问题描述】:

我总是得到错误设计者必须创建一个“BaseFractal”类型的实例,但不能因为它标记为“抽象”。没有任何解决方案 How can I get Visual Studio 2008 Windows Forms designer to render a Form that implements an abstract base class? 工作过

这个错误还有其他解决办法吗?

[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());
        
    

【问题讨论】:

不是直接的解决方案,但您可以定义一个派生自该抽象控件的默认具体控件,仅用于在设计器中查看。 【参考方案1】:

设计器在设计器中显示抽象控件没有任何问题。问题是当您的控件具有抽象基类时。

假设您有一个抽象BaseControl 作为MyControl 的基类。那么当你尝试在设计器中查看BaseControl时,没有问题,但是设计器无法显示MyControl

问题是因为当您在设计视图中打开 MyControl 时,设计器尝试创建基类的实例以在设计器中显示它,但由于基类是抽象的,因此无法创建实例并且无法加载。

作为解决该问题的一个选项,您可以创建一个从基控件派生的非抽象基类以用于调试模式。然后设计师可以显示MyControl

注意:使用 #if DEBUG 只是为了在为 RELEASE 构建时摆脱中间的非抽象基。如果你不关心它,你不需要这些指令,你可以创建中间的非抽象基并使用它。

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

这是我的摘要BaseControl

namespace SampleWinApp

    public abstract partial class BaseControl : UserControl
    
        public BaseControl()
        
            InitializeComponent();
        
    

【讨论】:

或者,您可以使用属性 - 请参阅我的答案【参考方案2】:

您可以使用抽象类上的属性来解决此问题,如下所示

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<MyBaseFormEf, Form>))]



    public class AbstractControlDescriptionProvider<TAbstract, TBase> : TypeDescriptionProvider
    
        public AbstractControlDescriptionProvider()
            : base(TypeDescriptor.GetProvider(typeof(TAbstract)))
        
        

        public override Type GetReflectionType(Type objectType, object instance)
        
            if (objectType == typeof(TAbstract))
                return typeof(TBase);

            return base.GetReflectionType(objectType, instance);
        

        public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
        
            if (objectType == typeof(TAbstract))
                objectType = typeof(TBase);

            return base.CreateInstance(provider, objectType, argTypes, args);
        
    

【讨论】:

以上是关于如何修复错误“设计者必须创建类型为“”的实例,但不能因为它标记为抽象”的主要内容,如果未能解决你的问题,请参考以下文章

如何修复:远程服务器返回错误:(400)错误请求

如何修复 WordPress 中的 HTTP 错误

如何修复 Ubuntu 中检测到系统程序错误的问题

如何修复“找不到名称'ClipboardItem'”错误?

如何修复 C++ 中的“分段错误”错误

分段错误错误(信号名称:SIGSEGV)的原因是啥,我将如何找到/修复它?