Search code examples
c#winformscustom-controlspropertygriddesign-time

Clear InnerList elements of a custom control property after delete custom control from a form in Design Mode


I add my created custom control to the new Windows Form and add some Tab to it by "Tabs" property. However, when I delete my custom control from Windows Form, elements of "Tabs" property are not removed. Please see below figures for more information:

My custom control "Tabs" property with its Collection Editor

Figure 1 - My custom control "Tabs" property with its Collection Editor

  1. Blue Box: "Tabs" property of my custom control
  2. Red Box: Added elements to the "Tabs" property

Figure 1 displays when I add some member to the Tabs property.

Windows Form project controls after add some member to the Tabs property

Figure 2 - Windows Form project controls after add some member to the Tabs property

  1. Red Box: My custom control
  2. Blue Box: Added elements to the Tabs property

Windows Form project controls after delete my custom control from Windows Form

Figure 3 - Windows Form project controls after delete my custom control from Windows Form

  • Red Box: Added elements to the Tabs property

As you can see in the figure 2 and 3, I add some member to the Tabs property and after delete my custom control from its parent control (Windows Form), Tabs property members have not been removed.

My Tabs property is related to the Tabs class that derived from CollectionBase class and implement some methods such as Add, Remove, Clear and, etc. to it. And I call Clear and RemoveRange methods in the Dispose method, but it doesn't work.

My codes as follows:

[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
[ToolboxItem(true), ToolboxBitmap(typeof(ToolboxIconResourceFinder), "FloorsGrouping.bmp")]
[DisplayName("Floors Group")]
[Editor("WindowsFormsControlLibrary2.FloorsGrouping, WindowsFormsControlLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=197889249da45bfc", typeof(UITypeEditor))]
[Description("Floorssssssss")]
[Category("Saino")]
//[DefaultEvent("")]
[DefaultProperty("Text")]
[DesignerCategory("Component")] //Form //Designer //Empty String ("")
public partial class FloorsGrouping : Bar
{
    private static Font fntDefaultFont = SystemFonts.DefaultFont;
    private static string strDefaultAccessibleDescription = "";
    private static string strDefaultAccessibleName = "";

    private bool canDockBottom = false;
    private bool canDockTop = false;
    private bool fadeEffect = true;
    private int selectedDockTab = 0;
    private eDotNetBarStyle style = eDotNetBarStyle.StyleManagerControlled;
    private string text = "Floors Grouping";
    private FloorsInformation floorsInformation = new FloorsInformation();
    private Tabs tabs = new Tabs();
    private SupportedLanguages language = SupportedLanguages.English;
    private Styles groupingStyles = Styles.Classic;

    public FloorsGrouping()
    {
        InitializeComponent();
        ResetFont();
        ResetAccessibleDescription();
        ResetAccessibleName();
    }

    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        Tab.Clear();
        Tab.RemoveRange(0, Tab.Count);
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    private new void ResetFont()
    {
        Font = fntDefaultFont;
    }

    private new bool ShouldSerializeFont()
    {
        return !Font.Equals(fntDefaultFont);
    }

    [Category("Data")]
    [DisplayName("Tabs")]
    [Description("Tabsssssssssssss")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [Editor(typeof(ItemsCollectionEditor), typeof(UITypeEditor))]
    //[Editor(typeof(ItemsCollectionEditor<SimilarFloorsInformation>), typeof(UITypeEditor))]
    //[Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
    public Tabs Tab
    {
        get
        {
            return tabs;
        }
    }

    [Category("Behavior")]
    [DisplayName("ContainerControl")]
    [Description("It indicates container control high lighter is bound to. It should be set to parent form.")]
    //[DefaultValue("")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    [Browsable(false), ReadOnly(true)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public Control ContainerControl
    {
        get { return hltMain.ContainerControl; }
        private set { hltMain.ContainerControl = this; }
    }

    protected override void OnParentChanged(EventArgs e)
    {
        ContainerControl = this;
    }
    protected override void OnCreateControl()
    {
        base.OnCreateControl();
    }

    protected override void OnControlRemoved(ControlEventArgs e)
    {
        //Tab.RemoveRange(0, tabs.Count);
        //Parent.Refresh();
        base.OnControlRemoved(e);
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        base.OnPaint(pe);
    }
}

[DisplayName("Floors Information")]
[Description("Floors Informationnnnnnnnnnnnnnnn")]
[DefaultProperty("Text")]
[DesignerCategory("Component")]
[ToolboxItem(false)]
public class FloorsInformation : DockContainerItem
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    private SimilarFloorsInformation similarFloorsInformation = new SimilarFloorsInformation();
    private AllFloorsInformation allFloorsInformation = new AllFloorsInformation();
    private string text = "Floors Information";

    public FloorsInformation()
    {
    }

    [Browsable(false), ReadOnly(true)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public new bool AutoCollapseOnClick
    {
        get { return base.AutoCollapseOnClick; }
    }

    [Browsable(false), ReadOnly(true)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public new Control Control
    {
        get { return base.Control; }
    }

    public new string Text
    {
        get
        {
            return text;
        }
        set
        {
            text = value;
        }
    }

    [Category("Data")]
    [DisplayName("Similar Floors Panel")]
    [Description("Similar Floors Panellllllllllllllllllll")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public SimilarFloorsInformation SimilarFloorsInfo
    {
        get
        {
            return similarFloorsInformation;
        }
        set
        {
            similarFloorsInformation = value;
        }
    }

    [Category("Data")]
    [DisplayName("All Floors Group")]
    [Description("All Floors Groupppppppppppppp")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public AllFloorsInformation AllFloorsInfo
    {
        get
        {
            return allFloorsInformation;
        }
        set
        {
            allFloorsInformation = value;
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
}

public class Tabs : CollectionBase
{
    public FloorsInformation this[int intIndex]
    {
        get
        {
            return (FloorsInformation)InnerList[intIndex];
        }
        set
        {
            InnerList[intIndex] = value;
        }
    }

    public int Add(FloorsInformation finfItemType)
    {
        return InnerList.Add(finfItemType);
    }

    public new void Clear()
    {
        InnerList.Clear();
    }

    public bool Contains(FloorsInformation finfItemType)
    {
        return InnerList.Contains(finfItemType);
    }

    public void Remove(FloorsInformation finfItemType)
    {
        InnerList.Remove(finfItemType);
    }

    public new void RemoveAt(int intIndex)
    {
        InnerList.RemoveAt(intIndex);
    }

    public void RemoveRange(int intIndex, int intCount)
    {
        InnerList.RemoveRange(intIndex, intCount);
    }

    public void Insert(int intIndex, FloorsInformation finfItemType)
    {
        InnerList.Insert(intIndex, finfItemType);
    }

    public void Reverse()
    {
        InnerList.Reverse();
    }

    public void Reverse(int intIndex, int intCount)
    {
        InnerList.Reverse(intIndex, intCount);
    }

    public int IndexOf(FloorsInformation finfItemType)
    {
        return InnerList.IndexOf(finfItemType);
    }

    public void AddRange(FloorsInformation[] finfItemType)
    {
        InnerList.AddRange(finfItemType);
    }

    public FloorsInformation[] GetValues()
    {
        FloorsInformation[] finfItemType = new FloorsInformation[InnerList.Count];
        InnerList.CopyTo(0, finfItemType, 0, InnerList.Count);
        return finfItemType;
    }

    protected override void OnInsert(int intIndex, object objValue)
    {
        base.OnInsert(intIndex, objValue);
    }

    protected override void OnClear()
    {
        base.OnClear();
    }
}

public class ItemsCollectionEditor : CollectionEditor
{
    private Type[] typItems;

    public ItemsCollectionEditor(Type typItem)
        : base(typItem)
    {
        typItems = new Type[] { typeof(FloorsInformation) };
    }

    protected override Type[] CreateNewItemTypes()
    {
        return typItems;
    }

    protected override CollectionForm CreateCollectionForm()
    {
        CollectionForm collectionForm = base.CreateCollectionForm();
        collectionForm.Text = "Tabs Collection Editor";
        return collectionForm;
        //return base.CreateCollectionForm();
    }
}

I want to do something like Bar controls of DevComponents.DotNetBar. Please see the following for more information:

Add Bar control to the Windows Form

Figure 4 - Add Bar control to the Windows Form

  1. Left Red Box: Added Bar control to the Windows Form
  2. Right Red Box: Added Bar control in the Property Grid of Visual Studio

When Bar control is added to the Windows Form, Property Grid changes as you can see in the Figure 4.

Create Dock Tab by "Bar Tasks" option

Figure 5 - Create Dock Tab by "Bar Tasks" option

  • Red Box: "Create Dock Tab" option under "Bar Tasks"

With "Create Dock Tab" option under "Bar Tasks," we can create a new Dock Tab for add fresh controls to specific tab of Bar control as you can see in the Figure 5.

Added Dock Container Item and its related Panel Dock Container

Figure 6 - Added Dock Container Item and its related Panel Dock Container

  1. Red Box: Added Bar control in the Property Grid of Visual Studio
  2. Left Blue Box: Added Dock Container Item control to the Bar control
  3. Right Blue Box: Added Dock Container Item control in the Property Grid of Visual Studio
  4. Left Green Box: Added Panel Dock Container control to the Dock Container Item control
  5. Right Green Box: Added Panel Dock Container control in the Property Grid of Visual Studio

Added Dock Container Items and its related Panel Dock Containers

Figure 7 - Added Dock Container Items and its related Panel Dock Containers

  1. Red Box: Please see Red Box of Figure 6
  2. Left Blue Box: Added Dock Container Item controls to the Bar control
  3. Right Blue Box: Added Dock Container Item controls in the Property Grid of Visual Studio
  4. Right Green Box: Added Panel Dock Container controls in the Property Grid of Visual Studio

Each time "Create Dock Tab" option is clicked under "Bar Tasks," a new Dock Container Item control with its related Panel Dock Container control is made in the Bar control of DevComponents.DotNetBar (Please see Figure 6 and 7).

Property Grid of Visual Studio after delete Bar control

Figure 8 - Property Grid of Visual Studio after delete Bar control

  • Red Box: Windows Form control in the Property Grid of Visual Studio

When Bar control is removed from Windows Form, all its related controls are removed with it, and only Windows Form remains.

I want to remove my "Tabs" property members automatically after my custom control deletes from its Parent control (Windows Form).


Solution

  • I found the solution. For remove "Tabs" property members automatically after deletion of custom control from its Parent control (Windows Form), must apply some changes to "Dispose" method of the "FloorsGrouping" class that inherited from "Bar" class. Please see following line of codes that must change:

    protected override void Dispose(bool disposing)
    {
        Tab.Clear();
        Tab.RemoveRange(0, Tab.Count);
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }
    

    Please see following line of codes that have changed for achieve to the goal:

    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
    
        if (Tab.Count > 0)
        {
            foreach (FloorsInformation floorsInformation in Tab)
            {
                floorsInformation.Dispose();
            }
        }
        base.Dispose(disposing);
    }