C# 自定义用于关闭单个选项卡的 TabControl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/803540/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:50:55  来源:igfitidea点击:

Customizing a TabControl for the Closing of Individual Tabs

c#winformsuser-interfacecontrolstabcontrol

提问by THE DOCTOR

My scenario is the following:

我的情况如下:

I am working on a winforms application in C# that has a button inside the main page of a tabcontrol that will generate another tabpage each time that it is clicked. Each new tabpage will contain a layout defined by a user control.

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

My Questions are:

我的问题是:

  1. How can I allow the user to then close one of the tabs that were created dynamically at runtime?

  2. How might I go about modifying the tabcontrol itself so that it has a small 'X' in each tab that the user may click on in order to close that particular tab? (Like Firefox has)

  3. How can I expose the SelectedIndex property of the tabcontrol to the user control if I want to close the tab with a button inside the user control instead?

  1. 我怎样才能允许用户关闭在运行时动态创建的选项卡之一?

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

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

采纳答案by Daniel Brückner

I created a derived tab control about one year ago. I am not going to post the source here, because it's about 700 lines long and coded quite messy. Maybe I will find some time to clean the code up and then release it here. For now I will briefly outline the way it is build.

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

Each tab page has a 'X' icon to the leftof the title and the tab pages support reordering by drag and drop and moving them between multiple tab control.

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

I choose the easy way to get the icon on the tab pages. The tab control has the TabControl.ImageListproperty and a tab page has a TabPage.ImageIndexproperty. So I just added three icons to a image list - normal, hover, pressed - and process the mouse events.

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

With TabControl.GetTabRect()you can test if the mouse is over a specific tab pages and with some math you find if it is over the icon. Then you just need to change the icon depending on the mouse button state and eventually remove the tab page under the mouse if the button was pressed.

有了TabControl.GetTabRect()你可以测试鼠标在一个特定的标签页,并与一些数学你会发现,如果它是在图标上。然后您只需要根据鼠标按钮状态更改图标,并最终在按下按钮时删除鼠标下方的标签页。

The main problem with this solution is, that calculating if the mouse is over the icon requires to know where the icon is painted relative to the tab page and this might change with a new windows version. And the icon is to the left of the title, but that does not look too bad.

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

回答by Chris Persichetti

I created a setup that is similar.

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

Each control that is added to the tab page at runtime is derived from a special base control I created. This base control has a close button (along with some other features such as safe to close flag).

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

Close tab code I'm using on my base control:

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

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

tabControl.TabPages.Remove(parent);

回答by Vallel

I found this code and was very helpful to me:

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

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

TabControl:如何在选项卡上捕获鼠标右键单击

回答by Mark Kram

I know this is an old thread but I did find this linkthat will allow you to "hide" tabs in an array and then you can just re-load the tabs you want at run time. I added this more for a place I can easily find it again.

我知道这是一个旧线程,但我确实找到了这个链接,它允许您“隐藏”数组中的选项卡,然后您可以在运行时重新加载所需的选项卡。我添加了这个更多的地方,我可以很容易地再次找到它。

回答by Muhammad Hamad

I did the following: on the create (add) TabPagestage, I added a toolStrip

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

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

Then, create the Xbutton and add it to toolstrip

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

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

create an event on clicking the Xbutton

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

ToolStripButton.Click += new EventHandler(ToolStripButton_Click);

add toolstripto the tabpage

添加toolstriptabpage

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

nowfor the ToolStripButton_Clickis as follows:

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

Maybe it is not as you want, but it will work well.

也许它不是你想要的,但它会运作良好。

回答by Eric

It′s works!

其作品!

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

回答by Mohammad Chamanpara

This code might help throgh closing the tab controls with middle mouse click :

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

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