Search code examples
c#designer

When I Delete The Control, It Remains Drawn To Form


I created a container control that lists radio buttons similar to how the CheckedListBox control lists check boxes. The control functions fine, but when I delete the control, the border and background remain drawn to the form in the designer. If I run the program with the deleted control, the control doesn't appear drawn, it only is drawn in the designer.

Here is a picture of the control in action:

enter image description here

And here is of when I've deleted the control (the form in the designer is to the left, the running form is to the right):

enter image description here

I suppose it's not really a problem, but why is this happening? Also, although it shows two squares, that's only because I added another one and deleted it.

Here's the code for the ChromeRadioButtonListBox and the base ChromeContainerControl:

public class ChromeRadioButtonListBox : ChromeContainerControl
{
    [Description("Determines what corner(s) will be rounded.")]
    public Utilities.RoundedRectangle.RectangleCorners Corners { get; set; }

    private int cornerRadius;
    [Description("Determines the radius of the the corners")]
    public int CornerRadius
    {
        get { return cornerRadius; }
        set
        {
            if (value < 1)
                Utilities.ThrowError("The radius cannot be less than 1. If you want no radius, set Corners to None.");
            else
                cornerRadius = value;
        }
    }

    [Description("Determines the list of ChromeRadioButton controls that are displayed.")]
    public ChromeRadioButton[] Items { get; set; }

    public ChromeRadioButtonListBox()
    {
        this.AutoScroll = true;
        this.CornerRadius = 1;
        this.Items = new ChromeRadioButton[0];
    }

    protected override void Dispose(bool disposing)
    {
        for (int i = 0; i < Items.Length; i++)
            Items[i].Dispose();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics canvas = e.Graphics;
        canvas.SmoothingMode = SmoothingMode.HighQuality;
        Rectangle region = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
        GraphicsPath path = Utilities.RoundedRectangle.Create(region, CornerRadius, Corners);
        canvas.FillPath(new LinearGradientBrush(region, fillColors[0], fillColors[1], 90), path);
        canvas.DrawPath(new Pen(borderColor), path);
        for (int i = 0; i < Items.Length; i++)
        {
            if (i == 0)
                Items[i].Location = new Point(2, 2);
            else
                Items[i].Location = new Point(2, Items[i - 1].Location.Y + Size.Ceiling(canvas.MeasureString(Items[i - 1].Text, Items[i - 1].Font)).Height);
            Controls.Add(Items[i]);
        }
    }
}



public abstract class ChromeContainerControl : ContainerControl, IDisposable
{
    public override Color BackColor
    {
        get
        {
            return base.BackColor;
        }
    }

    public Color borderColor;
    public Color[] fillColors;

    public ChromeContainerControl()
    {
        base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        base.SetStyle(ControlStyles.UserPaint, true);
        this.BackColor = Color.Transparent;
        this.borderColor = Scheme.DefaultBorderColor;
        this.fillColors = Scheme.DefaultFillColors;
        this.Font = new Font("Verdana", 8f);
        this.ForeColor = Color.FromArgb(70, 70, 70);
    }
}

Solution

  • As I suggested in my comment below your question call base.Dispose(disposing)

    protected override void Dispose(bool disposing)
    {
        for (int i = 0; i < Items.Length; i++)
            Items[i].Dispose();
    
        base.Dispose(disposing);
    }
    

    As you are overriding this method from the base class, it will only perform the operations you specify in that override. Calling the base.Dispose ensure that any cleanup performed in the base is also performed from your override.

    You can read more info on Dispose and Finaliser implementations at http://msdn.microsoft.com/en-gb/library/vstudio/b1yfkh5e(v=vs.100).aspx