Search code examples
c#winformspersistencedesigner

Persisting Design Time Properties in WinForms


I am writing a stylable control for Windows Forms. By stylable I mean the user has greater control over the appearance of the Control than the standard BackColor, ForeColor etc. The following code has been simplified to illustrate the problem

[ToolboxItem(false)]
public class BrushProperties : Component
{
    public Color[] GradientColors { get; set; }
    public Single[] GradientPositions { get; set; }
    public Single GradientAngle { get; set; }
}

[ToolboxItem(false)]
public class Style : Component
{
    public BrushProperties Background { get; set; }
    public BrushProperties Foreground { get; set; }

    public Style()
    {
         this.Background = new BrushProperties();
         this.Foreground = new BrushProperties();
    }
}

public class StyleControl : Control
{
    public Style Style { get; set; }

    public StyleControl()
    {
        this.Style = new Style();
    }
}

When I am in the designer I can see all of the properties of Style and all of the properties of each BrushProperties instance. I can change the values as well, but the moment I build/run the project, the values I've assigned to the properties disappear. What does my code require in order to persist the property values that are specified at design time?


Solution

  • If the goal is to have a design-time support, then you don't need to base all your classes from the Component object. Instead you could decorate your classes with the ExpandableObjectConverter attribute.

    The PropertyGrid will use the ExpandableObjectConverter attribute to determine whether if it should expand the properties of an object or not.

    Example:

    [ToolboxItem(false)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class BrushProperties
    {
      public Color[] GradientColors { get; set; }
      public Single[] GradientPositions { get; set; }
      public Single GradientAngle { get; set; }
    }
    
    [ToolboxItem(false)]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class Style
    {
      public BrushProperties Background { get; set; }
      public BrushProperties Foreground { get; set; }
    
      public Style()
      {
        this.Background = new BrushProperties();
        this.Foreground = new BrushProperties();
      }
    }