Creating Our Own TabControl In C#




Let's create a our own tabcontrol using Buttons & Panels. Create a C# Windows Forms Application project in Visual Studio.
I named it MyTabControl. I used simple customized buttons but you can create your own.
Step 1

Go to Project -> Add Class & enter name ButtonX and copy and paste following code. Well you know we need a button as a tab, but whenever click action is performed on that button, its back color must not changed but remaining buttons must changed whenever mouse enters or leaves.

In the following code, this action is controlled using isChanged boolean variable. Change the following code as you want to customize it.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Drawing;  
  5. using System.Data;  
  6. using System.Windows.Forms;  
  7. namespace MyTabControl  
  8. {  
  9.     public class ButtonX : System.Windows.Forms.Button  
  10.     {  
  11.         Color clr1;  
  12.         private Color color = Color.Teal;  
  13.         private Color m_hovercolor = Color.FromArgb(0, 0, 140);  
  14.         private Color clickcolor = Color.FromArgb(160, 180, 200);  
  15.         private int textX = 6;  
  16.         private int textY = -20;  
  17.         private String text = "_";  
  18.         private bool isChanged = true;  
  19.   
  20.         public String DisplayText  
  21.         {  
  22.             get { return text; }  
  23.             set { text = value; Invalidate(); }  
  24.         }  
  25.         public Color BXBackColor  
  26.         {  
  27.             get { return color; }  
  28.             set { color = value; Invalidate(); }  
  29.         }  
  30.         public Color MouseHoverColor  
  31.         {  
  32.             get { return m_hovercolor; }  
  33.             set { m_hovercolor = value; Invalidate(); }  
  34.         }  
  35.         public Color MouseClickColor1  
  36.         {  
  37.             get { return clickcolor; }  
  38.             set { clickcolor = value; Invalidate(); }  
  39.         }  
  40.         public bool ChangeColorMouseHC  
  41.         {  
  42.             get { return isChanged; }  
  43.             set { isChanged = value; Invalidate(); }  
  44.         }  
  45.         public int TextLocation_X  
  46.         {  
  47.             get { return textX; }  
  48.             set { textX = value; Invalidate(); }  
  49.         }  
  50.         public int TextLocation_Y  
  51.         {  
  52.             get { return textY; }  
  53.             set { textY = value; Invalidate(); }  
  54.         }  
  55.         public ButtonX()  
  56.         {  
  57.             this.Size = new System.Drawing.Size(31, 24);  
  58.             this.ForeColor = Color.White;  
  59.             this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;  
  60.             this.Text = "_";  
  61.             text = this.Text;  
  62.         }  
  63.         //method mouse enter  
  64.         protected override void OnMouseEnter(EventArgs e)  
  65.         {  
  66.             base.OnMouseEnter(e);  
  67.             clr1 = color;  
  68.             color = m_hovercolor;  
  69.         }  
  70.         //method mouse leave  
  71.         protected override void OnMouseLeave(EventArgs e)  
  72.         {  
  73.             base.OnMouseLeave(e);  
  74.             if (isChanged)  
  75.             {  
  76.                 color = clr1;  
  77.             }  
  78.         }  
  79.         protected override void OnMouseDown(MouseEventArgs mevent)  
  80.         {  
  81.             base.OnMouseDown(mevent);  
  82.             if (isChanged)  
  83.             {  
  84.                 color = clickcolor;  
  85.             }  
  86.         }  
  87.         protected override void OnMouseUp(MouseEventArgs mevent)  
  88.         {  
  89.             base.OnMouseUp(mevent);  
  90.             if (isChanged)  
  91.             {  
  92.                 color = clr1;  
  93.             }  
  94.         }  
  95.         protected override void OnPaint(PaintEventArgs pe)  
  96.         {  
  97.             base.OnPaint(pe);  
  98.             text = this.Text;  
  99.             if (textX == 100 && textY == 25)  
  100.             {  
  101.                 textX = ((this.Width) / 3) + 10;  
  102.                 textY = (this.Height / 2) - 1;  
  103.             }  
  104.             Point p = new Point(textX, textY);  
  105.             pe.Graphics.FillRectangle(new SolidBrush(color), ClientRectangle);  
  106.             pe.Graphics.DrawString(text, this.Font, new SolidBrush(this.ForeColor), p);  
  107.         }  
  108.     }  
  109. }   
Step 2

Go to Project -> Add User Control & enter name TabControlX. Give whatever back color to it and the components which we are going to add on it. 
 
Step 3
  • Add Panel on TabControlX, give it a BackTopPanel name, set Dock property to Top and Height to 40.
  • Add Panel on BackTopPanel, give it a RibbonPanel name, set Dock property to Bottom and Height to 2.
  • Add Panel on BackTopPanel, give it a TabButtonPanel name, Anchor to Left-Top-Right, set Location to (0,0) and specific Width leaving some extra portion of BackTopPanel at end and Height to 30.
  • Add ToolStrip on BackTopPanel, Set Dock property to None, Anchor to Top-Right, add DropDownButton from added ToolStrip and add DropDownOpening event to it.
  • Add Panel on TabControlX, give it a TabPanel name, set Dock property to Fill. 
Step 4

Go to Project -> Add User Control & enter name TabPanelControl. TabPanelControl is used to hold the components that we want to add to tabs. Download the source code.
 
Step 5

Now we need to create a list of buttons that represent tabs and a list of added components(TabPanelControl).
  1.        int selected_index = -1;  
  2.        public List<ButtonX> buttonlist = new List<ButtonX> { };  
  3.        public List<TabPanelControl> tabPanelCtrlList = new List<TabPanelControl> { };   
  4.       
  5.        void UpdateButtons()  
  6.        {  
  7.            if (buttonlist.Count > 0)  
  8.            {  
  9.                for (int i = 0; i < buttonlist.Count; i++)  
  10.                {  
  11.                    if (i == selected_index)  
  12.                    {  
  13.                        buttonlist[i].ChangeColorMouseHC = false;  
  14.                        buttonlist[i].BXBackColor = Color.FromArgb(20, 120, 240);  
  15.                        buttonlist[i].ForeColor = Color.White;  
  16.                        buttonlist[i].MouseHoverColor = Color.FromArgb(20, 120, 240);  
  17.                        buttonlist[i].MouseClickColor1 = Color.FromArgb(20, 120, 240);  
  18.                    }  
  19.                    else  
  20.                    {  
  21.                        buttonlist[i].ChangeColorMouseHC = true;  
  22.                        buttonlist[i].ForeColor = Color.White;  
  23.                        buttonlist[i].MouseHoverColor = Color.FromArgb(20, 120, 240);  
  24.                        buttonlist[i].BXBackColor = Color.FromArgb(40, 40, 40);  
  25.                        buttonlist[i].MouseClickColor1 = Color.FromArgb(20, 80, 200);  
  26.                    }  
  27.                }  
  28.   
  29.            }  
  30.        }  
  31.   
  32.        void createAndAddButton(string tabtext, TabPanelControl tpcontrol, Point loc)  
  33.        {  
  34.            ButtonX b = new ButtonX();  
  35.            b.DisplayText = tabtext;  
  36.            b.Text = tabtext;  
  37.            b.Size = new Size(130, 30);  
  38.            b.Location = loc;  
  39.            b.ForeColor = Color.White;  
  40.            b.BXBackColor = Color.FromArgb(20, 120, 240);  
  41.            b.MouseHoverColor = Color.FromArgb(20, 120, 240);  
  42.            b.MouseClickColor1 = Color.FromArgb(20, 80, 200);  
  43.            b.ChangeColorMouseHC = false;  
  44.            b.TextLocation_X = 10;  
  45.            b.TextLocation_Y = 9;  
  46.            b.Font = this.Font;  
  47.            b.Click += button_Click;  
  48.            TabButtonPanel.Controls.Add(b);  
  49.            buttonlist.Add(b);  
  50.            selected_index++;  
  51.   
  52.            tabPanelCtrlList.Add(tpcontrol);  
  53.            TabPanel.Controls.Clear();  
  54.            TabPanel.Controls.Add(tpcontrol);  
  55.   
  56.            UpdateButtons();  
  57.        }  
  58.   
  59.        void button_Click(object sender, EventArgs e)  
  60.        {  
  61.            string btext = ((ButtonX)sender).Text;  
  62.            int index = 0, i;  
  63.            for (i = 0; i < buttonlist.Count; i++)  
  64.            {  
  65.                if (buttonlist[i].Text == btext)  
  66.                {  
  67.                    index = i;  
  68.                }  
  69.            }  
  70.            TabPanel.Controls.Clear();  
  71.            TabPanel.Controls.Add(tabPanelCtrlList[index]);  
  72.            selected_index = ((ButtonX)sender).TabIndex;  
  73.   
  74.            UpdateButtons();  
  75.        }  
  76.   
  77.        public void AddTab(string tabtext, TabPanelControl tpcontrol)  
  78.        {  
  79.            if (!buttonlist.Any())  
  80.            {  
  81.                createAndAddButton(tabtext, tpcontrol, new Point(0, 0));  
  82.            }  
  83.            else  
  84.            {  
  85.                createAndAddButton(tabtext, tpcontrol, new Point(buttonlist[buttonlist.Count - 1].Size.Width + buttonlist[buttonlist.Count - 1].Location.X, 0));  
  86.            }  
  87.        }  
UpdateButtons() function just changes the back color of buttons but the selected index. createAndAddButton() function create a new object of class ButtonX, sets properties to it. Also adds an object of TabPanelControl to the TabPanel.

In button_Click function event, clears the controls of TabPanel and adds the control from tabPanelCtrlList of selected index. AddTab() is the function which we will call to add a tab on tabcontrol.
  1. private void toolStripButton1_DropDownOpening(object sender, EventArgs e)  
  2. {  
  3.     toolStripDropDownButton1.DropDownItems.Clear();  
  4.     int mergeindex = 0;  
  5.     for (int i = 0; i < buttonlist.Count; i++)  
  6.     {  
  7.         ToolStripMenuItem tbr = new ToolStripMenuItem();  
  8.         tbr.Text = buttonlist[i].Text;  
  9.         tbr.MergeIndex = mergeindex;  
  10.         if (selected_index == i)  
  11.         {  
  12.             tbr.Checked = true;  
  13.         }  
  14.         tbr.Click += tbr_Click;  
  15.         toolStripDropDownButton1.DropDownItems.Add(tbr);  
  16.         mergeindex++;  
  17.     }  
  18. }  
  19.   
  20. List<string> btstrlist = new List<string> { };  
  21. void BackToFront_SelButton()  
  22. {  
  23.     int i = 0;  
  24.   
  25.     TabButtonPanel.Controls.Clear();  
  26.     btstrlist.Clear();  
  27.     for (i = 0; i < buttonlist.Count; i++)  
  28.     {  
  29.         btstrlist.Add(buttonlist[i].Text);  
  30.     }  
  31.   
  32.     buttonlist.Clear();  
  33.   
  34.     for (int j = 0; j < btstrlist.Count; j++)  
  35.     {  
  36.         if (j == 0)  
  37.         {  
  38.             ButtonX b = new ButtonX();  
  39.             b.DisplayText = btstrlist[j];  
  40.             b.Text = btstrlist[j];  
  41.             b.Size = new Size(130, 30);  
  42.             b.Location = new Point(0,0);  
  43.             b.ForeColor = Color.White;  
  44.             b.BXBackColor = Color.FromArgb(20, 120, 240);  
  45.             b.MouseHoverColor = Color.FromArgb(20, 120, 240);  
  46.             b.MouseClickColor1 = Color.FromArgb(20, 80, 200);  
  47.             b.ChangeColorMouseHC = false;  
  48.             b.TextLocation_X = 10;  
  49.             b.TextLocation_Y = 9;  
  50.             b.Font = this.Font;  
  51.             b.Click += button_Click;  
  52.             TabButtonPanel.Controls.Add(b);  
  53.             buttonlist.Add(b);  
  54.             selected_index++;  
  55.         }  
  56.         else if (j > 0)  
  57.         {  
  58.             ButtonX b = new ButtonX();  
  59.             b.DisplayText = btstrlist[j];  
  60.             b.Text = btstrlist[j];  
  61.             b.Size = new Size(130, 30);  
  62.             b.ForeColor = Color.White;  
  63.             b.BXBackColor = Color.FromArgb(20, 120, 240);  
  64.             b.MouseHoverColor = Color.FromArgb(20, 120, 240);  
  65.             b.MouseClickColor1 = Color.FromArgb(20, 80, 200);  
  66.             b.ChangeColorMouseHC = false;  
  67.             b.TextLocation_X = 10;  
  68.             b.TextLocation_Y = 9;  
  69.             b.Font = this.Font;  
  70.             b.Click += button_Click;  
  71.             b.Location = new Point(buttonlist[j - 1].Size.Width + buttonlist[j - 1].Location.X, 0);  
  72.             TabButtonPanel.Controls.Add(b);  
  73.             buttonlist.Add(b);  
  74.             selected_index++;  
  75.         }  
  76.     }  
  77.     TabPanel.Controls.Clear();  
  78. }  
  79.   
  80. void tbr_Click(object sender, EventArgs e)  
  81. {  
  82.     int i;  
  83.     for (int k = 0; k < ((ToolStripMenuItem)sender).MergeIndex; k++)  
  84.     {  
  85.         int j = 0;  
  86.         for (i = ((ToolStripMenuItem)sender).MergeIndex; i >= 0; i--)  
  87.         {  
  88.             ButtonX but = buttonlist[i];  
  89.             ButtonX temp = buttonlist[j];  
  90.             buttonlist[i] = temp;  
  91.             buttonlist[j] = but;  
  92.   
  93.             TabPanelControl uct1 = tabPanelCtrlList[i];  
  94.             TabPanelControl tempusr = tabPanelCtrlList[j];  
  95.             tabPanelCtrlList[i] = tempusr;  
  96.             tabPanelCtrlList[j] = uct1;  
  97.         }  
  98.     }  
  99.   
  100.     string btext = ((ToolStripMenuItem)sender).Text;  
  101.     BackToFront_SelButton();  
  102.     selected_index = 0;  
  103.     TabPanel.Controls.Add(tabPanelCtrlList[buttonlist[0].TabIndex]);  
  104.     UpdateButtons();  
  105. }  
  106.   
  107.   
  108. public void RemoveTab(int index)  
  109. {  
  110.     if (index >= 0 && buttonlist.Count > 0 && index < buttonlist.Count)  
  111.     {  
  112.         buttonlist.RemoveAt(index);  
  113.         tabPanelCtrlList.RemoveAt(index);  
  114.         BackToFront_SelButton();  
  115.         if (buttonlist.Count > 1)  
  116.         {  
  117.             if (index - 1 >= 0)  
  118.             {  
  119.                 TabPanel.Controls.Add(tabPanelCtrlList[index - 1]);  
  120.             }  
  121.             else  
  122.             {  
  123.                 TabPanel.Controls.Add(tabPanelCtrlList[(index - 1) + 1]);  
  124.                 selected_index = (index - 1) + 1;  
  125.             }  
  126.         }  
  127.         selected_index = index - 1;  
  128.   
  129.         if (buttonlist.Count == 1)  
  130.         {  
  131.             TabPanel.Controls.Add(tabPanelCtrlList[0]);  
  132.             selected_index = 0;  
  133.         }  
  134.     }  
  135.     UpdateButtons();  
  136. }   
BackToFront_SelButton() bring the tab which is out of screen. First it copies all button text to btstrlist, clears the buttonlist, creates a new object and add each item again to buttonlist.

tbr_Click() function swaps the items from buttonlist and tabPanelCtrlList till the count of buttonlist. RemoveTab() function removes the entry of item from buttonlist and tabPanelCtrlList. 
 
Step 6
  • Now Debug your project.
  • Drag & Drop TabControlX onto Form.
  • You can use properties to access colors.
  • Download the source code.
  • To just add tab call function AddTab()
  1. tabControlX1.AddTab("TabPage 1"null);  
To add component to tabpage, first create an object of TabPanelControl, and add all controls on TabPanelControl object and then pass it as a parameter to AddTab() function
  1.          TabPanelControl tpc = new TabPanelControl();  
  2.          tpc.Dock = DockStyle.Fill;  
  3.          RichTextBox rtb = new RichTextBox();  
  4.          rtb.Dock = DockStyle.Fill;  
  5.          tpc.Controls.Add(rtb);  
  6.          tabControlX1.AddTab("RTB Tab ", tpc);  
I have added two buttons on Form1 and also added TabControlX. 
  1.       int cnt = 1;  
  2.       private void button1_Click(object sender, EventArgs e)  
  3.       {  
  4.           tabControlX1.AddTab("Tab "+cnt, null);  
  5.           cnt++;  
  6.       }  
  7.   
  8.       private void button2_Click(object sender, EventArgs e)  
  9.       {  
  10.           TabPanelControl tpc = new TabPanelControl();  
  11.           tpc.Dock = DockStyle.Fill;  
  12.           RichTextBox rtb = new RichTextBox();  
  13.           rtb.Dock = DockStyle.Fill;  
  14.           tpc.Controls.Add(rtb);  
  15.           tabControlX1.AddTab("Tab " + cnt, tpc);  
  16.           cnt++;  
  17.       }  
That's it.

Download the source code to view the tabcontrol source code also a little bit notepad implementation using our created tabcontrol. Here's the output.