Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

17 Aug 2009

Presenting ControlStateMachine

Here is a situation we are all familiar with: A form that only displays a certain set of controls depending on the mode or state of the application. Let me start with an example: At design time there are three buttons

screenshot of flowlayoutpanel with three buttons: edit, save and cancel.

The user can look at the data and decide to edit it:

screenshot of flowlayoutpanel with only one visible button: edit.

Or the user is editing the data and can decide to commit or discard her changes:

screenshot of flowlayoutpanel with two visible buttons: save and cancel.

A couple of years i ago i used to spread such display logic all over my code and it was hard to figure out which control was visible at a given point. Later on i refactored that code and encapsulated it in functions like: MakeControlsForDisplayVisible and MakeControlsForEditVisible which felt like a huge improvement. These days i have the feeling that a very simple state machine can improve the readability even better.

Ok, so how simple is simple? Currently the requirements list is pretty limited:

screenshot of unittests for controlstatemachine

Anyway, here is how i would write the code today (Yeah, for a stupid example this looks like overkill):

private void InitializeButtonLayoutPanelMachine()
{
controlStateMachine = new ControlStateMachine<displayAndEditStates>(buttonLayoutPanel);

controlStateMachine.WhenStateChangesTo(DisplayAndEditStates.Display)
.TheOnlyVisibleControlsAre(buttonEdit);

controlStateMachine.WhenStateChangesTo(DisplayAndEditStates.Edit)
.TheOnlyVisibleControlsAre(buttonSave, buttonCancel);
}

As always, here is the source: ControlStateMachine and WhenChangingState.