Designing Generic Forms
Did you know that Forms and UserControls can derive from a generic type in .NET 2.0?
For example, you might have a base form like this:
public partial class MyGenericForm<T> : Form
{
/* ... */
}
So this form can be constructed with a type at runtime and its behaviour might differ slightly depending on that type.
Why is that handy? Well, the handiness comes in deriving:
public partial class MyIntForm : MyGenericForm<int>
{
/* ... */
}
Now we have a form that specializes with "int" but inherits all the visual design (and other goodies) from MyGenericForm.
Great in theory, but there's one major catch - doing this means you can't switch to the visual form designer for MyIntForm. Visual Studio just isn't smart enough to construct a visual representation of a form that derives from a generic type.
So are we screwed? Not quite yet!
It's actually possible to fool Visual Studio into thinking that this is a standard, everyday form. You do this by defining a type to sit in between MyGenericForm and MyIntForm:
public class MyCustomIntForm : MyGenericForm<int> { } So this class does bugger all except derive from MyGenericForm and specialize with the "int" type. Then we adjust our original derived form thusly:
public partial class MyIntForm : MyCustomIntForm
{
/* ... */
}
... and voila! Now we have a form that derives (indirectly) from a generic type, and still works in the visual designer!
This example (using int as the specialized type) is a bit contrived, but I've already found one or two uses for this using my own classes as the type the form is based on. Let me know if it helps you!

Comments
# Jonathan Parker
2/10/2006 8:16 PM
Wow!
That is cool! I just can't get over how much generics makes code reuse easier.
Anyway generics also work with custom controls.
I blogged about a <a href="http://jonathanparker.com.au/JonathanParker/Web/blogs/jonathan/archive/2006/09/26/42.aspx">generic TextBox control</a> a while back.
What's great is being able call methods using different parameter types for converting between dates, times, numbers, strings etc.
I'm disappointed that you can't have generic properties.
I guess that's something that might be in .NET 3.0.
# Eliseu Rodrigues
12/10/2006 10:07 PM
It's a very smart workaround to this problem.
You saved my day.
Thank you.
# Paul Wilson
7/11/2006 2:14 AM
This is a top solution. Thanks
# Eric Stoffer
22/02/2007 3:10 AM
Thanks! that works great ... One other thing, i'm passing a parameter in my constructor so I then have to include the default (no parameters) constructor, which I'd rather not do ... see below
Eric Stoffer
public partial class frmTest : FormBaseTest
{
public frmTest (clsTest test) :base (test)
{
InitializeComponent();
}
...........
}
public class FormBaseTest: FormBase<clsTest>
{
public FormBaseTest(): base()
{
}
public FormBaseTest(clsTest businessObject)
: base(businessObject)
{
}
}
public class FormBase<baseType> : MyControls.FormBase
{
public baseType m_BusinessObject;
public FormBase()
{
}
public FormBase(baseType businessObject)
{
m_BusinessObject = businessObject;
}
}
# mabster
22/02/2007 7:00 AM
Eric,
I could be wrong, but I believe you can make your default constructor private (or protected) so that it's hidden to "users" of your form.
The designer will still be able to use it, since it uses reflection.
Try it out and see if it works.
Leave a Comment