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?
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.