Filini
Filini

Reputation: 2119

Generic base class for WinForm UserControl

I created a generic base class for a WinForm UserControl:

public partial class BaseUserControl<T> : UserControl
{
    public virtual void MyMethod<T>() 
    { 
        // some base stuff here 
    }
}

And a UserControl based on that:

public partial class MyControl : BaseUserControl<SomeClass>
{
    public override void MyMethod<SomeClass>() 
    { 
        // some specific stuff here 
        base.MyMethod<SomeClass>();
    }
}

It works fine, but MyControl cannot be edited in the VisualStudio Designer, because it says it cannot load the base class. I tried to define another class BaseUserControl, non generic, hoping it would load it, but the trick doesn't seem to work.

I already have a workaround: define an interface, IMyInterface<T>, and then create my control as

public partial class MyControl : UserControl, IMyInterface<SomeClass>

But I lose my base virtual methods (not a big deal, but still...).

Is there a way to create a base generic class for a UserControl, with the possiblity to edit it in the VisualStudio Designer?

Upvotes: 40

Views: 16335

Answers (3)

yoel halb
yoel halb

Reputation: 12711

Well this appears to be a bug in Visual studio.

By digging into the framework (actually by adding a RootDesignerSerializer with a custom type derived from CodeDomSerializer and overriding the serialize method), I was able to prove that the VS Code Dom provider is actually parsing wrong the generic classes, and instead of considering it as a generic class it is considering it as a regular class with the name class<T>, which Type.GetType() can of course not find.

I am still searching for a way to work around it, but in the mean time one can use the solutions above.

There is a Microsoft.Connect bug report on it, please vote on it at https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

Upvotes: 3

bernhardrusch
bernhardrusch

Reputation: 11890

We're doing the same thing and we work around by specializing a class first and derive from the specialized class. Using the code from your example this means something like:

public partial class UserControl : UserControlDesignable 
{

...
}
public class UserControlDesignable : BaseUserControl<Someclass> { }

The designer is still acting flaky sometimes - but most of the time it works.

Upvotes: 36

Frederik Gheysels
Frederik Gheysels

Reputation: 56934

You'll have to trick the designer by adding a 'regular' class that inherits from your generic base form. Your designable form should then inherit from this class. The following 2 class definitions are thus in the same file. You'll have to make sure that the class that inherits from the generic base user-control, is the last class in the file.

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

The designer will display the first class in the code file that it encounters.

Upvotes: 14

Related Questions