Abstract UserControl inheritance in Visual Studio designer
abstract class CustomControl : UserControl
{
protected abstract int DoStuff();
}
class DetailControl : CustomControl
{
protected override int DoStuff()
{
// do stuff
return result;
}
}
I dropped a DetailControl in a form. It renders correctly at runtime, but the designer displays an error and won't open because the base user control is abstract.
For the moment, I'm contemplating the following patch, which seems pretty wrong to me, as I want the child classes to be forced to implement the method.
class CustomControl : UserControl
{
protected virtual int DoStuff()
{
throw new InvalidOperationException("This method must be overriden.");
}
}
class DetailControl : CustomControl
{
protected override int DoStuff()
{
// do stuff
return result;
}
}
Anyone has a better idea on how to work my way around this problem?
What we want
First, let's define the final class and the base abstract class.
public class MyControl : AbstractControl
...
public abstract class AbstractControl : UserControl // Also works for Form
...
Now all we need is a Description provider.
public class AbstractControlDescriptionProvider<TAbstract, TBase> : TypeDescriptionProvider
{
public AbstractControlDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(TAbstract)))
{
}
public override Type GetReflectionType(Type objectType, object instance)
{
if (objectType == typeof(TAbstract))
return typeof(TBase);
return base.GetReflectionType(objectType, instance);
}
public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
{
if (objectType == typeof(TAbstract))
objectType = typeof(TBase);
return base.CreateInstance(provider, objectType, argTypes, args);
}
}
Finally we just apply a TypeDescriptionProvider
attribute to the Abstract control.
[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<AbstractControl, UserControl>))]
public abstract class AbstractControl : UserControl
...
And that's it. No middle control required.
And the provider class can be applied to as many Abstract bases as we want in the same solution.
You can use a TypeDescriptionProviderAttribute to provide a concrete design-time implementation for your abstract base class. See http://wonkitect.wordpress.com/2008/06/20/using-visual-studio-whidbey-to-design-abstract-forms/ for details.