views:

103

answers:

2

I've made it a personal rule to inherit every UI control before using it. In a previous life I'd always considered this one of the less useful things you could do because the justification always seemed to be "I might want to change the font on all the buttons at once"... a motivation that never paid off... once... ever.

Two recent projects have changed my mind about the practice, though. In the first, we needed a consistent "ValueChanged" event so that we could easily implement a "dirty" flag on our forms without a massive switch statement to choose between a Textbox's "TextChanged" event, or a ListBox's "SelectedIndexChanged" etc. We just wanted one consistent thing to listen for on all controls, and subclassing the built-in controls bought us that pretty easily.

In the second project, every effort was made to get by with the base controls because the UI was expected to be pretty simple, but a few months in, it became obvious that they just weren't going to cut it anymore, and we purchased the Telerik control suite. If we had inherited all the controls to begin with, then changing our derived controls to inherit from the Telerik controls would have applied the changes for us globally. Instead, we had to do some searching and replacing in all the form designers.

So here's my question: What are the relative strengths and weaknesses of

  1. Simply adding a Class, and making it inherit from a control.
  2. Adding a new "Custom Control" and inheriting.
  3. Adding a new "Component" and inheriting.

All three have the same effect in the end, you get a new type of Button to put on your forms. I've seen all three used by different people, and everyone seems to think that their way is the best. I thought I should put this discussion on StackOverflow, and maybe we can nail down a concensus as a community as to which one is the "right" way.

Note: I already have my personal opinion of which is "right", but I want to see what the world thinks.

+1  A: 

If both 1 & 2 are inheriting, then they are functionally identical, no? Should one of them be encapsulating a control? In which case you have a lot of pass-thru members to add. I wouldn't recommend it.

Peronally, I simply wouldn't add extra inheritance without a very good reason... for example, the "changed event" could perhaps have been handled with some overloads etc. With C# 3.0 this gets even cleaner thanks to extension methods - i.e. you can have things like:

public static AddChangeHandler(
        this TextBox textbox, EventHandler handler) {
    testbox.TextChanged += handler;
}
public static AddChangeHandler(
        this SomethingElse control, EventHandler handler) {
    control.Whatever += handler;
}

and just use myControl.AddChangeHandler(handler); (relying on the static type of myControl to resolve the appropriate extension method).

Of course, you could take a step back and listen to events on your own model, not the UI - let the UI update the model in a basic way, and have logic in your own object model (that has nothing to do with controls).

Marc Gravell
Mel
I like the extension method solution for wiring up the events, and will probably use that in the future. The second problem still stands, though. Eventually, most projects hit a point where the built-in controls are no longer adequate, and you'll want to migrate to third party controls.
Mel
It seems that voting the answer up caused it to go invisible... I'm going to try making it neutral again and see if it gets any attention. I'll upvote your answer again later on... don't worry.
Mel
I had hoped to spark a discussion with this one, but no-one else ever answered. Marc's answer is the best out of the two. I particularly liked the idea for accomplishing the same ends with extension methods. It's not quite as "encapsulatey" as I was trying for, but it brings up an interesting approach I hadn't considered.
Mel
A: 

I use composition. I simply create a new UserControl and add the controls I need. This works fine, because:

  • I never use that many properties anyway, so pass-through methods are kept to a minimum.
  • I can start with a naive approach and refine it later.
  • Properties for look and feel should be set consistently across the site. Now I can set them once and for all.
Thomas Eyde