C# 自定义用于关闭单个选项卡的选项卡控件 我的设想如下:

C# 自定义用于关闭单个选项卡的选项卡控件 我的设想如下:,c#,winforms,user-interface,controls,tabcontrol,C#,Winforms,User Interface,Controls,Tabcontrol,我正在用C#开发一个winforms应用程序,它在tabcontrol的主页中有一个按钮,每次单击该按钮时都会生成另一个tabpage。每个新选项卡页将包含由用户控件定义的布局 我的问题是: 如何允许用户关闭在运行时动态创建的其中一个选项卡 我该如何修改tabcontrol本身,使其在每个选项卡中都有一个小的“X”,用户可以单击该选项卡以关闭该特定选项卡?(就像Firefox一样) 如果我想用用户控件内的按钮关闭选项卡,如何将tabcontrol的SelectedIndex属性公开给用户控件 大

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

我的问题是:
  • 如何允许用户关闭在运行时动态创建的其中一个选项卡

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

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


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

    每个选项卡页的标题左侧都有一个“X”图标,选项卡页支持通过拖放和在多个选项卡控件之间移动来重新排序

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

    使用,您可以测试鼠标是否在特定的选项卡页面上,通过一些数学运算,您可以找到鼠标是否在图标上。然后,您只需根据鼠标按钮的状态更改图标,并最终在按下按钮时删除鼠标下的选项卡页面


    此解决方案的主要问题是,计算鼠标是否位于图标上方需要知道图标相对于选项卡页面的绘制位置,这可能会随着新windows版本的变化而变化。图标在标题的左边,但看起来还不错。

    我创建了一个类似的设置

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

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

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

    我发现这段代码对我很有帮助:

    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);
                 }
            }
        }
    }
    
    private void tabControl\u MouseUp(对象发送方,MouseEventArgs e)
    {
    //检查是否按下了鼠标右键
    if(e.Button==MouseButtons.Right)
    {
    //遍历所有选项卡页面
    for(int i=0;i

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

    我执行了以下操作: 在创建(添加)
    TabPage
    阶段,我添加了一个
    toolStrip

    ToolStrip ts = new ToolStrip();
    ts.Dock = DockStyle.Top;
    ts.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
    
    ToolStripButton ToolStripButton = new ToolStripButton("X");
    ts.Items.Add(ToolStripButton);
    
    然后,创建
    X
    按钮并将其添加到
    toolstrip

    ToolStrip ts = new ToolStrip();
    ts.Dock = DockStyle.Top;
    ts.RightToLeft = System.Windows.Forms.RightToLeft.Yes;
    
    ToolStripButton ToolStripButton = new ToolStripButton("X");
    ts.Items.Add(ToolStripButton);
    
    单击
    X
    按钮创建事件

    ToolStripButton.Click += new EventHandler(ToolStripButton_Click);
    
    toolstrip
    添加到
    tabpage

    tabControl1.TabPages[curenttabpage].Controls.Add(ts);
    
    现在对于
    工具条按钮,单击
    如下所示:

    void ToolStripButton_Click(object sender, EventArgs e)
    { 
     ToolStripButton t = (ToolStripButton)(sender);
     ToolStrip ts = t.Owner;
     TabPage tb = (TabPage)
     (ts.Parent);tabControl1.TabPages.Remove(tb);
    }
    
    也许它不是你想要的,但它会很好地工作。

    它很有效

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

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

                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;
                        }
                    }
                }
    
    private void tabControl1\u MouseDown(对象发送方,MouseEventArgs e)
    {
    if(e.Button!=System.Windows.Forms.MouseButtons.Middle)
    返回;
    对于(int i=0;i
    我没有。不幸的是,我甚至不再记得哪个项目包含了该控件。我会做一个项目,我仍然可以很容易地访问搜索,但机会渺茫,因为该项目可能已经存档了一段时间。如果你能找到他们将是伟大的。谢谢:)不走运。我猜这个项目仍然在SVN中,但是在迁移到TFS的过程中被存档了。没关系,伙计。我会挽起袖子做这件事。完成后将发布代码示例。谢谢你的努力。左边是红色的X,对吗?我更喜欢正确的答案,因为在我看来这似乎合乎逻辑:)答案很好。我想补充一点,如果您想在选项卡页面上使用DockStyle.Fill创建另一个控件,则需要在该控件之后添加ToolStrip~,否则ToolStrip将覆盖该控件的顶部。这不能通过调用“fill”控件上的BringToFront或SendToBack来解决。我过去使用过它,它实际上工作得很好:有任何答案有用吗?如果有,请接受。有完整源代码的最终解决方案吗?