Dr Drax Dr Drax - 3 months ago 46
C# Question

Why does custom tabcontrol disappear after rebuild or clean project?

Note: I don't wanna use WPF.

After I add my new tabcontrol to the form and add controls on tabpages it's ok, Until clean or rebuild the project(Surely build out!)!


when i clean or rebuild the project, every child control is gone and
didn't show on form but it exist on code designer!


my user control source code(tbBody is tabcontrol):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MZ_Multi_View
{
[Designer(typeof(MainDesigner))]
public partial class MZTabControl : UserControl
{
private bool isdesign = false;
private bool allowtbodyresize = false;
public MZTabControl()
{
InitializeComponent();
}
[Category("MZ TabControl"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TabControl TabControlArea
{
get
{
return tbBody;
}
}


my designer class:

public class MainDesigner : ParentControlDesigner
{
private DesignerVerbCollection dvc = new DesignerVerbCollection();
public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);

if (this.Control is MZTabControl)
{
this.EnableDesignMode(((MZTabControl)this.Control).TabControlArea, "TabControlArea");
var uc = (MZTabControl)component;

foreach (TabPage tbpg in uc.tbBody.TabPages)
{
EnableDesignMode(tbpg, tbpg.Name);
}
}
}
}


before rebuild or clean:
vs c# 2015 usercontrol - custom tabcontrol

after rebuild or clean:
vs c# 2015 usercontrol - custom tabcontrol

Answer

The designer of Form cant't see those TabPag controls to serialize them.

If number of tab pages is not constant

You can remove all items from TabPages collection of the TabControl in your UserControl and let the TabControl initialize without any tab then in your Form, add pages to the TabControl of your UserControl and all tabs and their contents will be serialized because this way the Form designer can see those tabs.

In this solution, you even don't need to call EnableDesignMode for all tab pages.

If number of tab pages is constant

If you have constant count of TabPage you can create public properties in your UserControl and enable designer of each tab page with name of corresponding property.

Example 1 - If number of tab pages is constant

using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyUserControl1Designer))]
public partial class UserControl1 : UserControl
{
    public UserControl1() { InitializeComponent(); }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public TabControl MyTabControl 
    {
       get { return this.tabControl1; } 
    }
    private void InitializeComponent()
    {
        this.tabControl1 = new System.Windows.Forms.TabControl();
        this.SuspendLayout();
        this.tabControl1.Name = "tabControl1";
        this.tabControl1.Dock = DockStyle.Fill;
        this.Controls.Add(this.tabControl1);
        this.Name = "UserControl1";
        this.ResumeLayout(true);
    }
    private System.Windows.Forms.TabControl tabControl1;
}
public class MyUserControl1Designer : ParentControlDesigner
{
    public override void Initialize(System.ComponentModel.IComponent component)
    {
        base.Initialize(component);
        this.EnableDesignMode(((UserControl1)this.Control).MyTabControl, "MyTabControl");
    }
}

In this solution if you want to initialize the TabControl with some tab pages, you can change your designer to this:

public class MyUserControl1Designer : ParentControlDesigner
{
    public override void Initialize(System.ComponentModel.IComponent component)
    {
        base.Initialize(component);
        this.EnableDesignMode(((UserControl1)this.Control).MyTabControl, "MyTabControl");
    }
    public override void InitializeNewComponent(System.Collections.IDictionary values)
    {
        base.InitializeNewComponent(values);
        AddTab();
        AddTab();
    }
    private void AddTab()
    {
        TabControl tabControl = ((UserControl1)this.Control).MyTabControl;
        var svc = (IDesignerHost)this.GetService(typeof(IDesignerHost));
        if (svc != null)
        {
            var tab1 = (TabPage)svc.CreateComponent(typeof(TabPage));
            tab1.Text = tab1.Name;
            tab1.UseVisualStyleBackColor = true;
            tabControl.TabPages.Add(tab1);
            var property = TypeDescriptor.GetProperties(tabControl)["Controls"];
            base.RaiseComponentChanging(property);
            base.RaiseComponentChanged(property, null, null);
        }
    }
}

Example 2 - If number of tab pages is constant

using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyUserControl2Designer))]
public partial class UserControl2 : UserControl
{
    public UserControl2() { InitializeComponent(); }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public TabControl MyTabControl
    { 
        get { return this.tabControl1; } 
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public TabPage T1 
    {
        get { return this.tabPage1; } 
    }
    private void InitializeComponent()
    {
        this.tabControl1 = new System.Windows.Forms.TabControl();
        this.tabPage1 = new System.Windows.Forms.TabPage();
        this.tabControl1.SuspendLayout();
        this.SuspendLayout();
        this.tabPage1.Name = "tabPage1";
        this.tabPage1.Text = "tabPage1";
        this.tabPage1.UseVisualStyleBackColor = true;
        this.tabControl1.Controls.Add(this.tabPage1);
        this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.tabControl1.Name = "tabControl1";
        this.Controls.Add(this.tabControl1);
        this.Name = "UserControl2";
        this.tabControl1.ResumeLayout(true);
        this.ResumeLayout(true);
    }
    private TabPage tabPage1;
    private System.Windows.Forms.TabControl tabControl1;
}
public class MyUserControl2Designer : ParentControlDesigner
{
    public override void Initialize(System.ComponentModel.IComponent component)
    {
        base.Initialize(component);
        this.EnableDesignMode(((UserControl2)this.Control).MyTabControl, "MyTabControl");
        this.EnableDesignMode(((UserControl2)this.Control).T1, "T1");
    }
}