I have a UserControl
which contains a TabControl
. I enabled the designer of the TabControl
and its TabPages
so the user can add/remove/modify tab pages and add controls to tab pages.
When I add my UserControl
to the Form
and add controls on tab pages it's OK and controls can be added/removed/changed properly until I build the project or save changes and close and reopen the form.
When I build the project, every changes that I'd made in tab pages and each controls which I added to tab pages are removed. The controls exists on
designer.cs
but they doesn't show on tab pages.
Why do the controls I added to tab pages of the TabControl of my UserControl disappear after rebuild?
My user control source code:
Note: tbBody
is a TabControl
[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 source code:
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: Screenshot
After rebuild or clean: Screenshot
The designer of Form
cant't see those TabPag
controls which you created in the UserControl
.
You can remove all items from TabPages
collection of the TabControl
in your UserControl
. If you need the TabControl
have some pages after adding to Form
you can add some tab pages in InitializeNewComponent
method of designer of your user control. Then user can change those pages or add/remove 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.
UserControl1
Create a public property for the TabControl
and decorate it with DesignerSerializationVisibility
by passing DesignerSerializationVisibility.Content
as value to say the designer serialize the content of control:
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(UserControl1Designer))]
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;
}
UserControl1Designer
Enable the designer of TabControl
using EnableDesignMode
method of the designer. Also initialize the TabControl
by adding 2 TabPage
like the job that the original control performs. To do so, you should use IDesignerHost
service like below.
public class UserControl1Designer : 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);
}
}
}
Then if you drag UserControl1
from toolbox and add it to the form, you can see the user control contains an editable tab control which contains 2 editable tab pages and all changes will be serialized and be persisted.
If you have a single or two pages in the TabContrl
of your UserControl
and you want to make them editabe, you should create public properties in your UserControl
and enable designer of each tab page with name of corresponding property.
Consider this note from remarks part of EnableDesignMode
:
The child does not directly participate in persistence, but it will if it is exposed as a property of the main control.
UserControl
You should have a public property for each TabPage
which you want to expose:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TabControl MyTabControl
{
get { return this.tabControl1; }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TabPage T1
{
get { return this.tabPage1; }
}
Designer
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");
}
}