65.9K
CodeProject 正在变化。 阅读更多。
Home

创建标签式 MDI 窗体

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (3投票s)

2008 年 11 月 1 日

CPOL

2分钟阅读

viewsIcon

64633

downloadIcon

3622

创建标签式 MDI 窗体的教程

tabbedMDI.PNG

引言

这是一个创建选项卡式 MDI 窗体的教程。通过这个步骤,你将了解创建选项卡式 MDI 窗体是多么容易。

背景

当我尝试制作一个文本编辑器时,我发现了这个技巧。

Using the Code

我创建了一个名为 frmChild 的第二个窗体。这是 MDI 子窗体的模板。但首先,创建一个 Parent 窗体,该窗体具有:选项卡容器、用于添加和删除的菜单/按钮、用于浏览选项卡的菜单。要将 Parent 窗体设置为 MDI parent,在属性窗口中,将 isMDIContainer = true。你可以添加菜单来列出你的 MDI 子窗体,但这是为了检查你的 MDI 子窗体是否与选项卡同步。不要忘记将子窗体的控件设置为 public,如果你希望从 Parent 窗体访问该控件。打开 frmChild.Designer.cs,导航到“Windows Form Designer generated code”区域下方。你将看到类似这样的内容

private System.Windows.Forms.RichTextBox richTextBox1; 

将该行更改为这样

public System.Windows.Forms.RichTextBox richTextBox1; 

就是这样!从这个例子来看,现在你可以从 Parent 窗体访问 richtextbox 了。从“添加”菜单单击事件(假设它名为 mnuAdd_Click),添加新的子窗体和选项卡,以及选项卡列表菜单

	private void mnuAdd_Click(object sender, EventArgs e)
        {
            frmChild newChild = new frmChild();   //add new child
            TabPage childTab = new TabPage();     //create new tab page
            newChild.MdiParent = this;            //set as child of this form
            newChild.Name = "Child" + createdTab.ToString();
            newChild.Text = " Child no " + createdTab.ToString();
            childTab.Name = newChild.Name;     
                     //make sure name and text are same
            childTab.Text = newChild.Text;       
                     //this is for synchronize later
            tabControl1.TabPages.Add(childTab);          //add new tab
            newChild.richTextBox1.Parent = childTab;     //attach to tab
            ToolStripMenuItem newMenuTab = new ToolStripMenuItem();   
                     //create menu to hold tab
            newMenuTab.Text = newChild.Text;                    
                     //make sure the name and text are same to synchronize later
            newMenuTab.Name = newChild.Name;
            mnuTab.DropDownItems.Add(newMenuTab);        //add menu item
            newMenuTab.Click += new EventHandler(newMenuTab_Click); 
                     //add event handler
            tabControl1.SelectTab(childTab);     
             //this is to make sure that tab page is selected in the same time
            newChild.Show();                                 
       //as new form created so that corresponding tab and child form is active
            createdTab++;   //increment of course
        }	

当单击选项卡列表菜单时,你选择一个选项卡,你希望相应的 Child 窗体也被激活。

void newMenuTab_Click(object sender, EventArgs e)
{            
   foreach (TabPage theTab in tabControl1.TabPages)
   {
       if (theTab.Text == sender.ToString ())   //sender is the clicked menu 
       { /*when menu is clicked, activate the corresponding form and tab page*/
          tabControl1.SelectTab(theTab);    /* when menu is clicked, select 
                    tab and activate MDI child*/
          foreach (Form WantToSelect in this.MdiChildren)
          {
             if (WantToSelect.Name == theTab.Name)    /*this is why you must 
	    make sure child form's and tab page's name are same for easier control*/
             {                                                                           
                 WantToSelect.Select();            //activate MDI child
              }
           } 
         }
    }
}

当然,你希望当你单击选项卡时,相应的 mdiChild 被选中。

private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
  foreach (frmChild  WantToSelect in this.MdiChildren )
  {
    if (tabControl1.SelectedTab != null) /*if no child has created, an error
                                will occur */
    {
       if (WantToSelect.Name == tabControl1.SelectedTab.Name)    /*again, this
 is why you must make sure child form's and tab page's name are same for 
easier control*/
       {                                                                           //
           WantToSelect.Select();  //activate MDI child
       }
     } 
   }
}

当关闭选项卡时,相应的 mdiChild 必须关闭。假设关闭菜单名为 mnuClose_Click

private void mnuClose_Click(object sender, EventArgs e)
{   
   mnuTab.DropDownItems.RemoveByKey(tabControl1.SelectedTab.Name);   
      //this is why you must make sure menu's and tab page's name are same
   this.ActiveMdiChild.Close();                  
      //because of synchronize routine, you must close the form first before tab.
   tabControl1.SelectedTab.Dispose();    
      //if tab first, activated tab will change and so the child form, 
      //this will be the closed form. The wrong form will close....
}

最后一点是激活与 Child 窗体相对应的选项卡的重要性。例如,访问 richtextbox 属性。

private void lblChar_Click(object sender, EventArgs e)
{
  frmChild childForm = (frmChild ) this.ActiveMdiChild ;  //this is the reason
          //why synchronization between tab and active MDI child is important
  lblChar.Text = "Char : " + childForm.richTextBox1.TextLength.ToString(); 
 
}

关注点

这只是示例代码,实际上,我没有在我的文本编辑器中使用 RichTextBox。相反,我使用的是 scintilla net wrapper。

历史

  • 2008 年 10 月 31 日:初始发布
© . All rights reserved.