EnumSelector is a control that allows to select one value from all possible values of enum type. This control simplify the creation of user interfaces which are based on enum types.

Select enum value with EnumSelector

Using the Control

EnumSelector control allows to select a value from all possible values of enum type. To use the control, You should inherit from EnumSelector with enum type.

The Selected property holds the current selected value. This property is always synchronized with the user interface. In other words, When the user selects a new enum value, the property value is updated to new selection immediately and when the property is updated in the program – the selected value in the user interface is selected and displayed.

When the user selects a new enum value, SelectionChanged event is raised. You can use the Selected property of the EnumSelector object which raised the event, to find out the new selected value.

By default, the names of the enum values will be displayed in the user interface. While this is very convenient, sometimes this is not suitable (For example, a more detailed name should be displayed, the jargon used to name the values is unfamiliar to the target audience or the values needs to be translated to another language). In this case, You can set AllowFormat property and override OnFormat method. This method accepts the enum value to be displayed and should return a string representation of the value which will be displayed on the user interface.

The Demo program

The demo program displays an image. It allows the user select which image will be displayed and how should it be displayed.In order to achieve this we create two EnumSelector.

DisplayStyleSelector

The DisplayStyleSelector allows the user to select how the image should be displayed. It is one of ImageLayout enum values: None,Tile,Zoom,Center and Stretch.

DisplayStyleSelector
public partial class DisplayStyleSelector : EnumSelector<ImageLayout> {
}

When the user selects a new ImageLayout value, we update the BackgroundImageLayout of the Picture Box.

SelectionChanged handler
private void winDisplayStyle_SelectionChanged(object sender,EventArgs e) {
  winPictureBox.BackgroundImageLayout = winDisplayStyle.Selected;
}

DisplayImageSelector

The user can also select one of the images to be displayed: rectangle in red, rectangle in yellow and rectangle in green. To implement this feature the we create a new enum DisplayImage and a new DisplayImageSelector. Please note that we change the displayed text in user interface by setting AllowFormat property in the constructor and overriding OnFormat which returns the name of the value with the prefix “Rectangle in “.

DisplayImageSelector
public enum DisplayImage : int {
  Green,
  Yellow,
  Red,
}
public partial class DisplayImageSelector : EnumSelector<DisplayImage> {
  public DisplayImageSelector() {
    AllowFormat = true;
  }
  public override string OnFormat(DisplayImage value) {
    return "Rectangle in " + value.ToString();
  }
}

When the user selects a new DisplayImage value, we update the BackgroundImage of the Picture Box based on the new selection.

SelectionChanged handler
private void winDisplayImage_SelectionChanged(object sender,EventArgs e) {
    switch ( winDisplayImage.Selected) {
        case DisplayImage.Green:
          winPictureBox.BackgroundImage = global::Napuzba.Demo.Properties.Resources.green;
          break;
        case DisplayImage.Yellow:
          winPictureBox.BackgroundImage = global::Napuzba.Demo.Properties.Resources.yellow;
          break;
        case DisplayImage.Red:
          winPictureBox.BackgroundImage = global::Napuzba.Demo.Properties.Resources.red;
          break;
    }
}

Control implementation

Creating the basic control

To create the control, choose in the project context menu Add > New Item ... > Visual C# Items > Windows Forms > UserControl. Type the name “EnumSelector.cs” and click Add. A new design screen of the new user control appears. Drag a ComboBox control into the design view and update its properties (Name) to winDropDown, DropDownStyle to DropDownList and Dock to Fill. Size the control to the desired height so the ComboBox will fill the entire space.

EnumSelector - step 1

Adding enum values

As we want this control to be display enum values we make it generic with the enum type TT

EnumSelector
public partial class EnumSelector<TT> : UserControl {

In the constructor we fill winDropDown with the enum values with help of Enum.GetValues

EnumSelector constructor
public EnumSelector() {
    InitializeComponent();
    foreach (Object oo in Enum.GetValues(typeof(TT))) {
        winDropdown.Items.Add((TT)oo);
    }
}

The selected property

The Selected property should be synchronized with the user interface – In Selected property setter we update winDropdown.SelectedItem to the value and the property getter will return the _selected field.

EnumSelector - selected property
public TT Selected {
  get {
    return _selected;
  }
  set {
    winDropdown.SelectedItem = value;
  }
}
private TT _selected;

The SelectionChanged event

To ensure that Selected property getter will always return the selected value in the user interface, we will add a new handler winDropdown_SelectionChanged to winDropDown’s SelectionChanged event using the properties window. We will also raise our SelectionChanged event.

EnumSelector - step 2

In this handler we will update the field and raise our SelectionChanged event.

EnumSelector - SelectionChanged event
public event EventHandler SelectionChanged;
private void winDropdown_SelectionChanged(object sender,EventArgs ee) {
  _selected = (TT)winDropdown.SelectedItem;
  if (SelectionChanged != null) {
    SelectionChanged(sender,ee);
  }
}

Updating display strings

In order to update names of the values, we add the OnFormat virtual method. We also add new handler winDropdown_Format to winDropDown’s Format event which allows to us to convert a value to its associated display string.

EnumSelector - OnFormat
public virtual string OnFormat(TT value) {
  return value.ToString();
}
private void winDropdown_Format(object sender,ListControlConvertEventArgs ee) {
  ee.Value = OnFormat((TT)ee.ListItem);
}

The AllowFormat property connect the handler to the event as requested

EnumSelector - AllowFormat property
public bool AllowFormat {
  get {
    return _allowFormat;
  }
  set {
    if (value == _allowFormat) {
      return;
    }
    _allowFormat = value;
    if (value) {
      winDropdown.Format += winDropdown_Format;
    } else {
      winDropdown.Format -= winDropdown_Format;
    }
  }
}
private bool _allowFormat = false;