Picking your base class wisely

One of the harder things to decide when you're starting out building a custom control is what to derive from. There are a couple different layers to the control hierarchy, and it's not always clear what to derive from.

Base class

What it adds

When to inherit from it


The IDisposable pattern on top of System.Object as well as the ability to be designed using the stuff in System.Design.

When you have an object with resources that you want to have the ability to be present on the design surface in some way.


Mouse, Painting, Keyboard handling

When you want Mouse, Painting, Keyboard handling, and you do not expect to host child controls in a public API.

ScrollableControl (inherits from Control)

Scrolling capabilities

As the docs suggest - you should not inherit from this class directly. If you want the control itself to be able to take focus, then inherit from Panel, and set ControlStyles.Selectable to true.


If you only want child controls to take focus, inherit from ContainerControl.


ContainerControl (inherits from ScrollableControl)

Advanced focus management.

A ContainerControl represents a control that can function as a container for other controls and provides focus management. Controls that inherit from this class can track the active control they contain, even when the focus moves somewhere within a different container.

ContainerControl objects provide a logical boundary for contained controls. The container control can capture the TAB key press and move focus to the next control in the collection

Note The container control does not receive focus; the focus is always set to the first child control in the collection of contained controls.


UserControl (Inherits from ContainerControl)

Adds Load Event and Friendly design surface

If you have a set of controls you wish to reuse at several different places, this class is handy as it has full designer support for just loading up that panel of items and designing it separately.

Form (Inherits from ContainerControl)

Adds Load Event, friendly design surface, and the ability to be a toplevel and/or topmost window.

Good for the main window of an application, MDI child windows, modal dialog windows, etc.

For reference, here's a picture of full class hierarchy from V1