Standardizing the development of custom controls

Over the past couple of months I got many opportunities to develop a variety of custom controls for WPF. Some of them are as basic as a Numeric TextBox and some are as complex as ElementFlow. It is interesting how many times the same set of patterns repeat themselves again and again. In this post I want to share a few ideas related to standardization of custom control development. I believe that such a thinking process could simplify creation of new custom controls.

Thinking in Tracks

A custom control is a combination of many features, each of which can be uniquely identified. I call each such feature a Track. Each track is theoretically orthogonal to other tracks but also has an ability to communicate through a defined interface and storage. You can think of tracks also as tracks from a song composition. A song consists of many audio + instrument tracks. Each of them are unique in themselves but also vary their tempo, volume, etc at different points in the song. Below is a simple depiction of tracks from the Mac OSX’s GarageBand application. The final song output is a combination / blend of these tracks.

image

Tracks in a custom control

A custom control is also made up of a variety of feature-tracks. From my past experiences I have compiled the following set of possible tracks:

image

  • Type: whether its a singular control like Button, list-based control like ListBox or hierarchical control like Tree
  • Selection: selections (single, multi) on list or hierarchical controls
  • Layout: layout of items in list or hierarchical controls
  • Hover: mouse hovers
  • Animation: for animating state changes
  • Virtualization: for handling large data-sets in list / hierarchical controls
  • Data: relates to data-binding
  • Rendering: the visual tree of the control

[Note that the tracks are pretty much pre-defined and well-known. I may have missed a track or two, but the general idea is that these tracks are all you need to create a broad range of controls.]

You have the flexibility to either include a track or totally skip it. Also a track could be added at anytime during the life of the control. In other words you can influence the behavior of a control by varying its tracks. You can create a new control by just combining a bunch of tracks that are relevant to that control. It is possible to create a repository of implementations for standard tracks, which can be used directly by new custom controls.

Many of these features are already provided by WPF. The point I want to make is that custom control development should become an act of combining the relevant tracks (and fine-tuning) than building these features by hand each time. Something like so:

1 CustomControl control = new CustomControl();
2 control.Tracks.Add(new ListTypeTrack());
3 control.Tracks.Add(new SelectionTrack());
4 control.Tracks.Add(new HoverTrack());
5 control.Tracks.Add(new VirtualizationTrack());
6 
7 dockPanel.Children.Add(control);
8 	
Finally…

I don’t have working code that does all of the above but in my most recent custom controls I have started adopting this technique. I am still far away from the picture I have drawn above. Also you may have noticed that I skipped talking about interactions between tracks. I will do that in a different post. I am certainly seeing a lot of benefits in this approach and moving forward this is probably how I will be developing controls.

Feel free to bug me for questions or comments.