添加到我的 UserControl 的 TabControl 的 TabPage 的控件在重建后消失

Controls added to TabPage of the TabControl of my UserControl disappear after rebuild

我有一个 UserControl,其中包含一个 TabControl。我启用了 TabControl 及其 TabPages 的设计器,因此用户可以 add/remove/modify 标签页并向标签页添加控件。

当我将我的 UserControl 添加到 Form 并在标签页上添加控件时,它没问题,控件可以 added/removed/changed 正确,直到我构建项目或保存更改并关闭和重新打开表格。

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.

为什么我添加到我的UserControl的TabControl标签页的控件在重建后消失了?

我的用户控件源码:

注:tbBody是一个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;
        }
    }
}

我的设计器源代码:

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);
            }
        }
    }
}

重建或清理之前:Screenshot
重建或清理后:Screenshot

Form 的设计者看不到您在 UserControl 中创建的那些 TabPag 控件。

您可以删除 UserControlTabControlTabPages collection 中的所有项目。如果您需要 TabControl 添加到 Form 后有一些页面,您可以在用户控件的设计器的 InitializeNewComponent 方法中添加一些标签页。然后用户可以将这些页面或 add/remove 页面更改为您的 UserControlTabControl 并且所有选项卡及其内容将被序列化,因为这样 Form 设计人员可以看到这些选项卡.

UserControl1

TabControl 创建一个 public 属性 并通过传递 DesignerSerializationVisibility.Content 作为值来用 DesignerSerializationVisibility 装饰它,表示设计者序列化内容控制:

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

使用设计器的EnableDesignMode方法启用TabControl的设计器。还通过添加 2 TabPage 来初始化 TabControl,就像原始控件执行的作业一样。为此,您应该使用如下所示的 IDesignerHost 服务。

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);
        }
    }
}

然后,如果您从工具箱中拖动 UserControl1 并将其添加到表单中,您可以看到用户控件包含一个可编辑的选项卡控件,其中包含 2 个可编辑的选项卡页面,所有更改都将被序列化并持久化。

备注

如果您的 UserControlTabContrl 中有一个或两个页面,并且您想让它们成为可编辑的,您应该在 UserControl 中创建 public 属性] 并启用每个标签页的设计器,名称对应 属性.

EnableDesignMode 的备注部分考虑此注释:

The child does not directly participate in persistence, but it will if it is exposed as a property of the main control.

用户控件

对于每个要公开的 TabPage,您应该有一个 public 属性:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TabControl MyTabControl
{ 
    get { return this.tabControl1; } 
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TabPage T1 
{
    get { return this.tabPage1; } 
}

设计师

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");
    }
}