Architecture – Why Should Form Inheritance Be Avoided?

Architecturedesignerwinforms

I remember learning VB4 and dragging a button onto a form, double-clicking on that button, and typing code into that event handler I had just been magically blessed with. Coming from QBASIC I was thrilled with the "V" in "VB", the visual designer was literally the best thing since sliced bread.

Of course you could do all that programmatically but the magic of the "V" was so appealing you just couldn't help but drag that button. We were encouraged to take that route.

But then a few years ago I started learning about C# and the .net framework and was fascinated by the way everything I thought I knew had just gone out the window. There's a lot of magic going on in VB6 that's completely unveiled in .net: take constructors and the InitializeComponents method for example. In the latter you'd find all the control instances you've dragged from the toolbox, all the events you've registered and the properties you've set in the designer.

And that's fine… I guess. It's just, I feel like I don't "own" what's going on, this code that I can only modify via the designer annoys the heck out of me. Every time you copy a button that says "Ok" from one form to another (sometimes along with its brother "Cancel"), you are actually duplicating code, and that's a sin isn't it? DRY, don't repeat yourself, says the Pope.

Religions and schools of thought aside, in all objectivity, shouldn't we derive forms from base forms instead, and have the "Ok" button (and all of its friends) live on the base form? Something like a FormBase from which derives a DialogFormBase; all classes created in no time… by typing code. The buttons are created depending on how the class is instanciated (i.e. a constructor enum argument determines which buttons are to be created), controls are laid out inside an arrangement of split panels and flow layout panels, injected into the form as Content that fits into the main content panel. Isn't this what ASP.net does with master pages and content placeholders? I'd derive a form when I need a new "master page", but this new "master page" still derives from a base form class so the visuals are consistent across the entire application.

To me that's much more code reuse than anything else I've ever done with the designer in WinForms, and it wasn't even hard, and code isn't cluttered with a 200-lines method that I have no control over, I can put comments where I like, they won't get overwritten by a designer. I guess it's just a matter of patterns and architecture, which is what brought me to this link: Best design for Windows forms that will share common functionality, where I realized I was spot on, except the answer there, suggests exactly what I'm doing, but it's advising against form inheritance because of designer considerations. That's the part I don't get. I would rather advise against using the designer because of code structure considerations, especially in regards with form and control inheritance, which I see no reason to avoid other than well it breaks the designer.

We can't all be just lazy, so what part am I missing?

Best Answer

I'm gonna oppose you with different paradigm : Favor composition over inheritance.

Even when you start writing GUI code by hand and use inheritance to share behavior and visuals between forms, you will hit same problem as normal OOP design. Lets say you have DialogForm, that has OK/Cancel buttons and GridForm, that has grid. You derive all dialogs from DialogForm and all forms with Grid from GridForm. And then you find out you want form with both. How would you solve it? If you are using form inheritance, then there is no way solve it. On the other side, if you are using UserControls, then you can simply put GridControl on your form and be done with it. And you can still use designer with UserControls, so you don't have to waste time writing tedious GUI code.