Custom property Checkbox wrapper as Dynamic Property in EPiServer 7.5

We needed to add a checkbox as a dynamic property in my current client’s EPiServer 7.5 site last week. It’s not as straight forward as one might think due to the way that dynamic properties are handled. If you add a dynamic checkbox property through admin mode, together with a property decorated with the [Ignore] attribute in your code, everything will work fine up until when you start trying to overwrite inherited values on subpages. For instance: If you first tick the checkbox on the site’s start page and inherit it to all the underlying pages, and then try to override the value on some part of the subtree, it won’t accept the overridden value. Apparently EPiServer won’t replace a true value with nothing.

A possible semi acceptable solution could have been to create one of them pretty drop down lists with Yes and No values by implementing EPiServer’s ISelectionFactory interface, and decorating the property with [SelectOne(SelectionFactoryType = typeof(MyPropertySelectionFactory))]. However, this won’t work as it’s a dynamic property and EPiServer’s attribute decoration won’t bite.

Working checkbox in EPiServer’s dynamic properties

I implemented a simple checkbox wrapper in the form of a legacy custom property that works just as well with EPiServer 7.5 as it did back in the day. The wrapper takes the appearence of a checkbox when rendered in edit mode, but persists the value as a string rather than a boolean type. This helps EPiServer overriding the data correctly.

PropertyCheckboxWrapper.cs

[Serializable]
[PropertyDefinitionTypePlugIn(
  DisplayName = "Checkbox wrapper",
  Description = "Some description"
)]
public class PropertyCheckboxWrapper : PropertyString
{
  public override PropertyData ParseToObject(string value)
  {
    return new PropertyCheckboxWrapper {String = value};
  }

  public override IPropertyControl CreatePropertyControl()
  {
    return new PropertyCheckboxWrapperControl();
  }
}

PropertyCheckboxWrapperControl.cs

public class PropertyCheckboxWrapperControl : PropertyDataControl
{
  private CheckBox _checkBox;
		
  public PropertyCheckboxWrapper PropertyCheckBox
  {
    get { return PropertyData as PropertyCheckboxWrapper; }
  }

  public override void CreateEditControls()
  {
    _checkBox = new CheckBox();
    ApplyControlAttributes(_checkBox);
    Controls.Add(_checkBox);
    SetupEditControls();
  }

  protected override void SetupEditControls()
  {
    var currentValue = PropertyCheckBox.Value as string;
    _checkBox.Checked = currentValue != null && Constants .PropertyValues.CheckboxWrapper.Selected.Equals(currentValue);
  }

  public override void ApplyEditChanges()
  {
    SetValue(CurrentValue);
  }

  private string CurrentValue
  {
    get
    {
      return _checkBox.Checked ?
            Constants.PropertyValues.CheckboxWrapper.Selected :
            Constants.PropertyValues.CheckboxWrapper.NotSelected;
    }
  }
}

Constants.cs

public static class Constants
{
  public static class PropertyValues
  {
    public static class CheckboxWrapper
    {
      // String representations
      public const string Selected = "true";
      public const string NotSelected = "false";
    }

When this is done you will be able to add the wrapper as any other type when you create dynamic properties in admin mode, and once your base page type class contains a little bit of logic like below you will find that you are now able to override the values.

[Ignore]
public virtual bool SomeCheckboxProperty
  {
    get
    {
      var someProperty = Property["SomeCheckboxProperty"];
      if (someProperty == null)
      {
        return false;
      }
      var value = someProperty.Value as string;
      return value != null &&
             Constants.PropertyValues.CheckboxWrapper .Selected.Equals(value);
    }
}