1

I have a base Form in VS2022:

public partial class DetailViewBase<TEntity> : Form
    where TEntity : class, new()
{
    // For Designer
    private DetailViewBase()
    {
    }

    public DetailViewBase(int? id)
    {
      Id = id;
    }
    ...
}

When I try to create a new form that should inherit from the base Form (Add -> New Item -> Inherited Form), the base Form is not shown in "Inheritance picker". Without generics, it is shown. Is it not possible to inherit (this way)? When I just base my other forms on the base form like this

public partial class Article : DetailViewBase<Article>

it works but I don't see the base Form's controls, that's why I tried to go via Inheritance picker

Jimi
  • 29,621
  • 8
  • 43
  • 61
IngoB
  • 2,552
  • 1
  • 20
  • 35

2 Answers2

2

The Inherited Form wizard cannot show your base Form class among the available compatible classes because the derived class needs to define the concrete Type of T; the Inheritance Picker offers no means to specify this.

You can simply create a new Form, then change the Type it inherits from and the Type of the generic type parameters defined in the base class.
E.g., create a Form named SomeDerivedForm:

public partial class SomeDerivedForm : Form {
    public SomeDerivedForm() => InitializeComponent();
}

then change it in (no changes in the Designer.cs file):

public partial class SomeDerivedForm : SomeBaseForm<SomeType> {
    public SomeDerivedForm() => InitializeComponent();
}

The design of generic classes, without an intermediate non-generic class, is available since Visual Studio 2015 Update 1 (.NET Framework)


Other problems in the code presented here that prevent the derived class to show Controls added to the base class (or to function entirely for that matter):

  • The default Constructor should not be private, it should be - if that is required - internal or protected internal
  • Of course the default Constructor must call the InitializeComponent() method
  • Overloaded Constructors should call the default Constructor first

In your case, the code can be changed in:

public partial class DetailViewBase<TEntity> : Form where TEntity : class, new()
{
    internal DetailViewBase() => InitializeComponent();

    public DetailViewBase(int? id) : this() {
      Id = id;
    }

    // [...]
}

In the Designer.cs file, the class is defined as:

partial class DetailViewBase<TEntity> { //[...] }

Some more information related to the initialization sequence in a derived Form:
How to get the size of an inherited Form in the base Form?

Jimi
  • 29,621
  • 8
  • 43
  • 61
-1

In Visual Studio, the "Inheritance Picker" dialog may not show the generic base forms directly. However, you can still manually inherit from your generic base form by modifying the code. When you use the "Inheritance Picker," it only shows non-generic base classes that can be inherited directly.

To inherit from a generic base form, you can do it manually in the code as you mentioned:

public partial class Article : DetailViewBase<Article>
{
    // Your form code here
}

However, if you want the controls from the generic base form to be visible in the derived form, you can follow these steps:

  1. Open your derived form (e.g., Article.cs) in the designer.
  2. At the top of the designer file (e.g., Article.Designer.cs), add the following using directive:
using YourNamespaceToDetailViewBase;
  1. In the designer file, change the base class of your form to the generic base form:
public partial class Article : DetailViewBase<Article>
{
    // Form code here
}
  1. Save and close the designer file.

After making these changes, your derived form (Article) should now inherit from the generic base form (DetailViewBase<Article>) with the controls visible in the designer.

Keep in mind that manually modifying the designer file might cause issues if you make changes using the Visual Designer. Be careful and always back up your files before making such modifications.

  • Thank you. My problem was that after "manually deriving", the base form's controls were not shown, but this had to do with the constructor calls (see accepted answer). – IngoB Aug 02 '23 at 14:05