Abstract generic UserControl inheritance in Visual Studio designer
Asked Answered
P

1

6

In one of my projects I'm using an abstract UserControl. To be able to design this control in Visual Studio I'm using the code proposed in this answer. Now I want to use this with another abstract UserControl which is also generic. But if I do

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<MyBaseControl<T>, UserControl>))]

I'm getting the compiler error

CS0416: an attribute argument cannot use type parameters

Removing the type parameter obviously doesn't compile either.

I can't derive MyBaseControl from a non generic base class because it already derives from an generic base class, so I tried decorating it with an interface and use it like so:

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<IMyBaseControl, UserControl>))]

This does compile but when I open the the design view my control doesn't get rendered, instead I get the error

The number of generic arguments provided doesn't equal the arity of the generic type definition.

Is there a way to solve this?

Protoxide answered 8/7, 2016 at 8:49 Comment(1)
Arributes don't work in the same way with generics, hence why [TypeDescriptionProvider(typeof because it can't use the genericsDagney
E
4

I suppose you have a control AbstractGenericBase<T> : GenericBase<T> which GenericBase<T> is a control having such definition: GenericBase<T>: UserControl.

So if you want to show AbstractGenericBase<T> in designer, you can use this code:

using System.ComponentModel;
using System.Windows.Forms;

#if DEBUG
public abstract partial class AbstractGenericBase<T> : NonGenericBase
#else
public partial class AbstractGenericBase<T> : GenericBase<T>
#endif
{
    public AbstractGenericBase()
    {
        InitializeComponent();
    }
}
#if DEBUG
public class NonGenericBase : GenericBase<object> { }
#endif

Note

  • The goal is showing this class in designer:
    public abstract partial class AbstractGenericBase<T> : GenericBase<T>
  • If T has some type constraints, instead of object in GenericBase<object> use a Dummy which satisfies the generic constraints.
  • The solution is based on this fact: When the designer wants to show your control in design surface, it tries to create an instance of base class of your control. When the base class of your control is a generic class the designer doesn't know how to create an instance of base class.
    In above solution, for design-time support, we said to designer the base for our control is NonGenericBase, but for run-time, we keep GenericBase<T> as base class of our control.
Eustoliaeutectic answered 10/7, 2016 at 12:35 Comment(2)
The goal is showing this class in designer: public abstract partial class AbstractGenericBase<T> : GenericBase<T>. Let me know if your goal is different.Eustoliaeutectic
Thank you, this works. I want to add that you have to either give the non generic class an other name than the generic one or keep it in a different file. Otherwise you get the error The type '<class name>' is made of several partial classes in the same fileRealtor

© 2022 - 2024 — McMap. All rights reserved.