Visual Studio 2019 / Generic Forms + Inheritance Issues

Viewed 103

In our Project we have the following class structure for our forms:

public partial class InterceptorForm : Form

public partial class EntityPage<T> : InterceptorForm where T : IDBEntityWithId

Every Form within the application now either inherits from InterceptorForm directly, or is an extension of the EntityPage<T>, for example:

public partial class PurchaseOrderPage : EntityPage<PurchaseOrder>

InterceptorForm provides very Basic stuff, such as Logs for Button-Clicks, Form-Values, etc.

EntityPage<T> provides all the generic functionality around entities (CRUD + stuff)

So, this works fine and as intended, also during runtime. However, after the first Debug-Run of the application, VisualStudio somehow gets stuck with the child forms EntityPage<T>. The designer now fails to load these forms, with - what it seems - one of two error messages:

1.)

GenericArguments[0], 'Project.DBConnection.PurchaseOrder', on Project.Client.Forms.EntityPage'1[T]' violates the constraint of type parameter 'T'.

2.)

The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: PurchaseOrderPage --- The base class 'Project.Client.Forms.EntityPage`1' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.

Now, the only thing that helps is: Cleaning, Building, Closing all Forms, Restarting VS, Cleaning, Building - and then it works again, until the application is debugged again.

Any Idea what kind of "Hick-Up" VS has with that particular code?

Especially the error about EntityPage could not be loaded is strange - because that file works in the Designer all the time.

Only thing to mention is that the classes implementing IDBEntityWithID are in a different Project, which is added as dependency. (The Project.DBConnection namespace)

This is annoying, because DesignTime is actually the only time, where these Generic-Forms are handy - cause then VS knows the type of

T entity (in `EntityPage<T>`)

And code in the implementing forms comes down to

entity.MethodOfPurchaseOrder();

rather than

((PurchaseOrder)entity).MethodOfPurchseOrder();
1 Answers

I've now found this post about .net 2.0 and just tested the same out of curiosity. What should I say, It works :) http://madprops.org/blog/designing-generic-forms/

Leaving the question here, maybe there is a more elegant solution, or somebody is facing the same issue:

Adding a non-generic class in between resolves the issue:

public partial class InterceptorForm : Form

public partial class EntityPage<T> : InterceptorForm where T : IDBEntityWithId

public partial class PurchaseOrderPageStub : EntityPage<PurchaseOrder>

public partial class PurchseOrderPage : PurchaseOrderPageStub

where the stub just passes on the constructors:

public partial class PurchaseOrderPageStub : EntityPage<PurchaseOrder>
{
    public PurchaseOrderPageStub() : base() => InitializeComponent();

    public PurchaseOrderPageStub(PurchaseOrder purchaseOrder, PageModes pageMode) : base(purchaseOrder, pageMode) => InitializeComponent();

    public PurchaseOrderPageStub(long entityId, PageModes pageMode) : base(entityId, pageMode) => InitializeComponent();
}

Now the "Stub" cannot be viewed in Designer after debugging the project once - but that's something we can live with.

Related