Customizing a TabControl for the Closing of Indivi

2019-01-15 12:02发布

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.

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?

7条回答
Anthone
2楼-- · 2019-01-15 12:50

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.

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

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

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.

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.

查看更多
Melony?
3楼-- · 2019-01-15 12:57

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);
查看更多
Ridiculous、
4楼-- · 2019-01-15 12:58

I know this is an old thread but I did find this link that 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.

查看更多
成全新的幸福
5楼-- · 2019-01-15 13:02

It´s works!

TabPage tabpage = (TabPage)this.Parent;
TabControl tabControl = (TabControl)tabpage.Parent;
tabControl.TabPages.Remove(tabpage);
查看更多
三岁会撩人
6楼-- · 2019-01-15 13:03

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

查看更多
聊天终结者
7楼-- · 2019-01-15 13:03

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;
                    }
                }
            }
查看更多
登录 后发表回答