【问题标题】:Customizing a TabControl for the Closing of Individual Tabs自定义 TabControl 以关闭单个选项卡
【发布时间】:2010-10-22 15:47:42
【问题描述】:

我的场景如下:

我正在使用 C# 开发一个 winforms 应用程序,该应用程序在 tabcontrol 的主页内有一个按钮,每次单击该按钮时都会生成另一个选项卡页。每个新标签页都将包含由用户控件定义的布局。

我的问题是:

  1. 如何允许用户关闭在运行时动态创建的选项卡之一?

  2. 如何修改 tabcontrol 本身,使其在每个选项卡中都有一个小“X”,用户可以单击它来关闭该特定选项卡? (就像 Firefox 一样)

  3. 如果我想用用户控件内的按钮关闭选项卡,如何将选项卡控件的 SelectedIndex 属性公开给用户控件?

【问题讨论】:

标签: c# winforms user-interface controls tabcontrol


【解决方案1】:

大约一年前,我创建了一个派生的选项卡控件。我不打算在这里发布源代码,因为它大约有 700 行长并且编码非常混乱。也许我会找时间清理一下代码,然后在这里发布。现在我将简要概述它的构建方式。

每个标签页的标题左侧都有一个“X”图标,标签页支持通过拖放重新排序并在多个标签控件之间移动它们。

我选择在标签页上获取图标的简单方法。选项卡控件具有TabControl.ImageList 属性,而选项卡页具有TabPage.ImageIndex 属性。所以我只是在图像列表中添加了三个图标——正常、悬停、按下——并处理鼠标事件。

使用TabControl.GetTabRect(),您可以测试鼠标是否在特定的标签页上,并通过一些数学运算发现它是否在图标上。然后你只需要根据鼠标按钮状态改变图标,如果按钮被按下,最终删除鼠标下的标签页。

这个解决方案的主要问题是,计算鼠标是否在图标上需要知道图标相对于标签页的绘制位置,这可能会随着新的 Windows 版本而改变。图标在标题的左侧,但看起来还不错。

【讨论】:

  • 我没有。不幸的是,我什至不记得哪个项目包含该控件。我将搜索我仍然可以轻松访问的项目,但机会很小,因为该项目可能在一段时间前已存档。
  • 如果你能找到它们会很棒。谢谢:)
  • 不走运。我猜该项目仍在 SVN 中,但在迁移到 TFS 期间已存档。
  • 没关系,伙计。我会挽起袖子去做。完成后将发布代码示例。感谢您的所有努力。
  • 红 X 在左边,是吗?我更喜欢right,因为这对我来说似乎是合乎逻辑的:)
【解决方案2】:

我创建了一个类似的设置。

在运行时添加到标签页的每个控件都派生自我创建的特殊基本控件。这个基本控件有一个关闭按钮(以及一些其他功能,例如安全关闭标志)。

关闭我在基本控件上使用的选项卡代码:

 TabPage tabpage = (TabPage)this.Parent;
TabControl tabControl = (TabControl)tabpage.Parent;

tabControl.TabPages.Remove(parent);

【讨论】:

    【解决方案3】:

    我找到了这段代码,对我很有帮助:

    private void tabControl_MouseUp(object sender, MouseEventArgs e)
    {
        // check if the right mouse button was pressed
        if(e.Button == MouseButtons.Right)
        {
            // iterate through all the tab pages
            for(int i = 0; i < tabControl1.TabCount; i++)
            {
                // get their rectangle area and check if it contains the mouse cursor
                Rectangle r = tabControl1.GetTabRect(i);
                if (r.Contains(e.Location))
                {
                    // show the context menu here
                    System.Diagnostics.Debug.WriteLine("TabPressed: " + i);
                 }
            }
        }
    }
    

    TabControl: How To Capture Mouse Right-Click On Tab

    【讨论】:

      【解决方案4】:

      我知道这是一个旧线程,但我确实找到了这个link,它允许您“隐藏”数组中的选项卡,然后您可以在运行时重新加载您想要的选项卡。我添加了更多内容,以便我可以轻松再次找到它。

      【讨论】:

        【解决方案5】:

        我做了以下事情: 在创建(添加)TabPage 阶段,我添加了一个toolStrip

        ToolStrip ts = new ToolStrip();
        ts.Dock = DockStyle.Top;
        ts.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
        

        然后,创建X 按钮并将其添加到toolstrip

        ToolStripButton ToolStripButton = new ToolStripButton("X");
        ts.Items.Add(ToolStripButton);
        

        在单击X 按钮时创建一个事件

        ToolStripButton.Click += new EventHandler(ToolStripButton_Click);
        

        toolstrip 添加到tabpage

        tabControl1.TabPages[curenttabpage].Controls.Add(ts);
        

        现在ToolStripButton_Click如下:

        void ToolStripButton_Click(object sender, EventArgs e)
        { 
         ToolStripButton t = (ToolStripButton)(sender);
         ToolStrip ts = t.Owner;
         TabPage tb = (TabPage)
         (ts.Parent);tabControl1.TabPages.Remove(tb);
        }
        

        也许它不是你想要的,但它会很好用。

        【讨论】:

        • 很好的答案。我要补充一点,如果您打算使用 DockStyle.Fill 在选项卡页上添加另一个控件,则需要在该控件之后添加 ToolStrip ~after~,否则 ToolStrip 将覆盖它的顶部。这无法通过在“填充”控件上调用 BringToFront 或 SendToBack 来解决。
        【解决方案6】:

        成功了!

        TabPage tabpage = (TabPage)this.Parent;
        TabControl tabControl = (TabControl)tabpage.Parent;
        tabControl.TabPages.Remove(tabpage);
        

        【讨论】:

          【解决方案7】:

          此代码可能有助于通过单击鼠标中键关闭选项卡控件:

                      private void tabControl1_MouseDown(object sender, MouseEventArgs e)
                      {
                          if (e.Button != System.Windows.Forms.MouseButtons.Middle)
                              return;
          
                          for (int i = 0; i < MainTabControl.TabPages.Count; i++)
                          {
                              if (this.MainTabControl.GetTabRect(i).Contains(e.Location))
                              {
                                  this.MainTabControl.TabPages.RemoveAt(i);
                                  return;
                              }
                          }
                      }
          

          【讨论】:

            猜你喜欢
            • 2011-02-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多