.net中的TabControl控件可以在设计时添加TabPage,而且会自动在代码中的多处加代码,如:
public class Form1 : System.Windows.Forms.Form
{
                  ......
private System.Windows.Forms.TabPage tabPage1;
                  ......
private void InitializeComponent()
{
......
this.tabPage1 = new System.Windows.Forms.TabPage();
......
this.SuspendLayout();
......
this.tabControl1.Controls.Add(this.tabPage1);
......
// 
// tabPage1
// 
this.tabPage1.Location = new System.Drawing.Point(4, 21);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(192, 75);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "tabPage1";
......
}
我现在试着自己做一个TabCotrol控件,当我自定义 CodeDomSerializer后,
我只能往itializeComponent中的某一个地方加一段连续的代码,我并不能
象上面一样往多处加,我更不能做到在itializeComponent上面写下面这行:
private System.Windows.Forms.TabPage tabPage1;请专家出手

解决方案 »

  1.   

    你照着自动生成的做,没问题啊。
    public Form1()
    {
    //
    // Windows 窗体设计器支持所必需的
    //
    InitializeComponent(); //
    // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
    // System.Windows.Forms.TabControl tabControl2= new System.Windows.Forms.TabControl();
    System.Windows.Forms.TabPage tabPage5=new System.Windows.Forms.TabPage();
    tabControl2.SuspendLayout();

    tabControl2.Controls.Add(tabPage5);
    tabControl2.Location = new System.Drawing.Point(260, 56);
    tabControl2.Name = "tabControl2";
    tabControl2.SelectedIndex = 0;

    tabPage5.Location = new System.Drawing.Point(4, 21);
    tabPage5.Name = "tabPage5";
    tabPage5.Size = new System.Drawing.Size(192, 75);
    tabPage5.TabIndex = 0;
    tabPage5.Text = "tabPage5"; this.Controls.Add(tabControl2);
    tabControl2.ResumeLayout(false);
    }我运行没有问题啊。
      

  2.   

    不需要用到 CodeDomeSerializer,TabControl 可以动态添加代码的“奥秘”在于它的设计器:System.Windows.Forms.Design.TabControlDesigner,重载的 Verbs 属性告诉 VS TabControl 在设计时有两个命令谓词“添加页面”和“移除页面”,注意它们的响应函数 OnAdd 和 OnRemove,OnAdd 首先创建了一个“设计器事务”DesignerTransaction 的实例(类似 SqlTransaction 的概念),然后调用那个 IDesignerHost.CreateComponent 方法创建一个新的 TabPage 并指定 Text;OnRemove 则相反,调用 IDesignerHost.DestroyComponent 方法销毁 TabControl 当前选中的 TabPage。所有的代码添加和移除都是由实现 IDesignerHost 接口的类实现的,并不需要 CodeDomeSerializer。
      

  3.   

    请参考 TabControlDesigner 类的关键代码:namespace System.Windows.Forms.Design
    {
        using System;
        using System.Collections;
        using System.ComponentModel;
        using System.ComponentModel.Design;
        using System.Design;
        using System.Drawing;
        using System.Security.Permissions;
        using System.Windows.Forms;    [SecurityPermission(SecurityAction.Demand, UnmanagedCode=true)]
        internal class TabControlDesigner : ParentControlDesigner
        {
            private void OnAdd(object sender, EventArgs eevent)
            {
                TabControl control1 = (TabControl) base.Component;
                MemberDescriptor descriptor1 = TypeDescriptor.GetProperties(base.Component)["Controls"];
                IDesignerHost host1 = (IDesignerHost) this.GetService(typeof(IDesignerHost));
                if (host1 == null)
                {
                    return;
                }
                DesignerTransaction transaction1 = null;
                try
                {
                    try
                    {
                        object[] objArray1 = new object[1] { base.Component.Site.Name } ;
                        transaction1 = host1.CreateTransaction(System.Design.SR.GetString("TabControlAddTab", objArray1));
                        base.RaiseComponentChanging(descriptor1);
                    }
                    catch (CheckoutException exception1)
                    {
                        if (exception1 != CheckoutException.Canceled)
                        {
                            throw exception1;
                        }
                        return;
                    }
                    TabPage page1 = (TabPage) host1.CreateComponent(typeof(TabPage));
                    string text1 = null;
                    PropertyDescriptor descriptor2 = TypeDescriptor.GetProperties(page1)["Name"];
                    if ((descriptor2 != null) && (descriptor2.PropertyType == typeof(string)))
                    {
                        text1 = (string) descriptor2.GetValue(page1);
                    }
                    if (text1 != null)
                    {
                        page1.Text = text1;
                    }
                    control1.Controls.Add(page1);
                    base.RaiseComponentChanged(descriptor1, null, null);
                }
                finally
                {
                    if (transaction1 != null)
                    {
                        transaction1.Commit();
                    }
                }
            }        private void OnRemove(object sender, EventArgs eevent)
            {
                TabControl control1 = (TabControl) base.Component;
                if ((control1 == null) || (control1.TabPages.Count == 0))
                {
                    return;
                }
                MemberDescriptor descriptor1 = TypeDescriptor.GetProperties(base.Component)["Controls"];
                TabPage page1 = control1.SelectedTab;
                IDesignerHost host1 = (IDesignerHost) this.GetService(typeof(IDesignerHost));
                if (host1 == null)
                {
                    return;
                }
                DesignerTransaction transaction1 = null;
                try
                {
                    try
                    {
                        object[] objArray1 = new object[2] { page1.Site.Name, base.Component.Site.Name } ;
                        transaction1 = host1.CreateTransaction(System.Design.SR.GetString("TabControlRemoveTab", objArray1));
                        base.RaiseComponentChanging(descriptor1);
                    }
                    catch (CheckoutException exception1)
                    {
                        if (exception1 != CheckoutException.Canceled)
                        {
                            throw exception1;
                        }
                        return;
                    }
                    host1.DestroyComponent(page1);
                    base.RaiseComponentChanged(descriptor1, null, null);
                }
                finally
                {
                    if (transaction1 != null)
                    {
                        transaction1.Commit();
                    }
                }
            }        public override DesignerVerbCollection Verbs
            {
                get
                {
                    if (this.verbs == null)
                    {
                        this.removeVerb = new DesignerVerb(System.Design.SR.GetString("TabControlRemove"), new EventHandler(this.OnRemove));
                        this.verbs = new DesignerVerbCollection();
                        this.verbs.Add(new DesignerVerb(System.Design.SR.GetString("TabControlAdd"), new EventHandler(this.OnAdd)));
                        this.verbs.Add(this.removeVerb);
                    }
                    this.removeVerb.Enabled = this.Control.Controls.Count > 0;
                    return this.verbs;
                }
            }
            // Fields
            private bool disableDrawGrid;
            private int persistedSelectedIndex;
            private DesignerVerb removeVerb;
            private bool tabControlSelected;
            private DesignerVerbCollection verbs;
        }
    }
      

  4.   

    请教ET2004:TabControlDesigner 类的关键代码在哪找的?
      

  5.   

    To  xiaoyaxiaoya(荛子) : 我是说我在自己做一个TabControl,而要实现所有设计时的东西.正在紧张研究ET2004的方案(兴奋中)
      

  6.   

    ET2004(ET2004),高,实在是高,请问你在哪找到的源码?
      

  7.   

    搞定!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!强烈请教ET2004:TabControlDesigner 类的关键代码在哪找的?
      

  8.   

    用 Reflecter 反编译 .NET Framework 的程序集 System.Design.dll 即可。如果可以给 Reflecter 装个 FileDisasseble 插件,甚至可以将整个 .NET Framework 的所有程序集反编译成 C# 源代码文件。
      

  9.   

    BTW: 自定义设计器(Customized Designer)是组建/控件开发的必修课,而且设计器也并不是什么秘密啊。
      

  10.   

    呵呵,ET2004真是好人。对了,有谁需要FileDissambler的,可以给我发短消息。作者的主页好像很久不能上了。觉得FileDissambler还不是特别方便,只能一个Assembly一起Dump,最好能一个类一个类的dump。呵呵,随便说说,看人挑担不吃力。
      

  11.   

    Amazon上的几本介绍Custom Control设计的书好像评价都很烂,唯一一本好点的只有:
    《User Interfaces in C#: Windows Forms and Custom Controls》呵呵。