来自抽象 base-Form 的控件在被 child 表单继承时不显示

Controls from abstract base-Form not shown when inherited by a child Form

我遵循 Juan Carlos Diaz 提供的解决方案 here

我的问题是我没有在具体 class 中看到任何抽象 class 的表单控件。我期待他们在那里,这样我就可以使用设计编辑器和具体的 class.

以下是我采取的步骤:

  1. 创建一个新的解决方案
  2. 创建一个新的 winforms 项目 (.Net 4.5.2)
  3. 创建一个名为 AbstractBaseForm.cs 的表单,并添加一些 hello world 逻辑:

  1. abstract关键字添加到AbstractBaseForm.cs;您的代码应如下所示:

    public abstract partial class AbstractBaseForm : Form
    {
        protected AbstractBaseForm()
        {
            InitializeComponent();
        }
    
        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = "Hello World";
        }
    }
    
  2. 将以下 class 添加到您的项目中:

    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);
        }
    }
    
  3. 将以下属性添加到 AbstractBaseForm.cs:

    [TypeDescriptionProvider(typeof (AbstractControlDescriptionProvider<AbstractBaseForm, Form>))]
    public abstract partial class AbstractBaseForm : Form
    {
    
  4. 向项目添加第二个表单,标题为 ConcreteForm.cs 并让它继承自 AbstractBaseForm.cs,如下所示:

    public partial class ConcreteForm : AbstractBaseForm
    {
        public ConcreteForm()
        {
             InitializeComponent();
        }
    }
    
  5. 更改 program.cs 使其加载 ConcreteForm.cs 如下:

    Application.Run(new ConcreteForm());
    
  6. 执行项目。您应该会看到 ConcreteForm.cs 加载,单击按钮会将标签更改为 "Hello World"。

  7. 关闭应用程序,然后单击 ConcreteForm.cs,调出其设计视图。你会看到这个:

为什么我在设计视图中看不到从 AbstractBaseForm.cs 继承的控件?

添加对基本构造函数的调用

public partial class ConcreteForm : AbstractBaseForm
{
    public ConcreteForm() : base()
    {
         InitializeComponent();
    }
}

正如@hans-passant 建议的那样,删除抽象关键字。使用 abstract 关键字后,我收到以下错误:

The designer must create an instance of type 'WindowsFormsApplication1.Form1' but it cannot because the type is declared as abstract.