如何修复错误“设计者必须创建类型“”的实例但不能,因为它标记为抽象”
How to fix the errror 'The designer must create an instance of type " " but cant because it marked abstract"
我总是收到错误设计者必须创建类型 "BaseFractal" 的实例但不能,因为它标记为抽象'。 None 个解决方案
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());
}
}
设计器在设计器中显示抽象控件没有任何问题。问题是当您的控件具有抽象基础 class.
假设您有一个抽象 BaseControl
作为 MyControl
的基础 class。那么当你尝试在设计器中看到BaseControl
时,没有问题,但是设计器无法显示MyControl
。
问题是因为当您在设计视图中打开 MyControl
时,设计器会尝试创建基础 class 的实例以在设计器中显示它,但是由于基础 class 是抽象的,它无法创建实例并且无法加载。
作为解决问题的一个选项,您可以创建一个非抽象的基 class 从用于调试模式的基控件派生。然后设计者可以显示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();
}
}
}
您可以使用抽象 class 上的属性解决此问题,如下所示
[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);
}
}
我总是收到错误设计者必须创建类型 "BaseFractal" 的实例但不能,因为它标记为抽象'。 None 个解决方案 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());
}
}
设计器在设计器中显示抽象控件没有任何问题。问题是当您的控件具有抽象基础 class.
假设您有一个抽象 BaseControl
作为 MyControl
的基础 class。那么当你尝试在设计器中看到BaseControl
时,没有问题,但是设计器无法显示MyControl
。
问题是因为当您在设计视图中打开 MyControl
时,设计器会尝试创建基础 class 的实例以在设计器中显示它,但是由于基础 class 是抽象的,它无法创建实例并且无法加载。
作为解决问题的一个选项,您可以创建一个非抽象的基 class 从用于调试模式的基控件派生。然后设计者可以显示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();
}
}
}
您可以使用抽象 class 上的属性解决此问题,如下所示
[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);
}
}