Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / GDI+

Beveled Panel with Shadow Effect - Now With Tabs

4.90/5 (5 votes)
2 Feb 2018CPOL2 min read 17.3K   559  
This is an alternative for Beveled Panel with Shadow Effect

Introduction

This is a modified version of AdvancedPanel that allows drawing tabs and rotated text.

V 2.0  The improved second version: AdvancedTabPanel_CP2.zip.

Image 1

Background

I liked the original AdvancedPanel but missed a tab drawing routine, so I decided to add a DrawTab routine in the modified AdvancedTab version. I also added a rotated text drawing routine DrawRotatedTabText.

Using the Code

The AdvancedTabPanel acts as a container for controls. For simple purposes, this is the only control that needs to be changed, in the designer, the following properties can be set:

  • TabCount
  • TabText
  • TabActive

For more advanced usage, AdvancedTab controls can be used individually, using the following properties:

  • TabNumber
  • TabText
  • TabFont
  • TabSelected
  • TabColorSelected
  • TabColorUnselected
  • TabFontColor
  • RotatedTextAngle
  • RotatedTextOffsetX
  • RotatedTextOffsetY

Do not forget to attach event handlers to the tabs like this:

C#
private void Form1_Shown(object sender, EventArgs e)
{
    foreach (var tabpanel in this.advancedTabPanel1.Tabs)
    {
        // Attach event handler to all tabs.
        tabpanel.Click += this.TabClick;
    }
}

private void TabClick(object sender, EventArgs e)
{
    BevelPanel.AdvancedTab tab = sender as BevelPanel.AdvancedTab;
    this.labelNumber.Text = tab.TabNumber.ToString();
    this.label1.Text = tab.Name + " click";
    this.advancedTabPanel1.TabActive = tab.TabNumber;
}

New in V2.0

The AdvancedTabPanel now has designer support for placing controls on tabs, and there is no need to change the parent property of controls anymore !

To allow changing the Tag property of controls when in design mode in the AdvancedTabPanel, the designer mode is determined as follows:

C#
designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
 
Then in the AdvancedTabPanel_Paint() method, the Tag will be set (only if it's empty).
Note that in the designer, you cannot click on a tab to change the current tab, you have to set the AdvancedTabPanel TabActive property.
Note that when a control has a Tag that is not numeric, it will always be displayed, no matter what tab page has been selected.
In the example, the labels labelNumber and labelStatus are treated this way, the buttons however have Tag number 1 and will only be displayed on tab page 1.
 
The code of the Main form is now simplified to this:
 
C#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PanelExample
{
    /// <summary>
    /// Demonstrates <see cref="BevelPanel.AdvancedTabPanel"/> 
    /// a modified version of AdvancedPanel containing a List of tabs.
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.advancedTabPanel1.TabActive = 1;
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            foreach (var tabpanel in this.advancedTabPanel1.Tabs)
            {
                // Attach event handler to all tabs.
                tabpanel.Click += this.TabClick;
            }
        }

        /// <summary>
        /// Note that labelNumber and labelStatus do not have a number as Tag and 
        /// will be visible on all tab pages.
        /// </summary>
        private void TabClick(object sender, EventArgs e)
        {
            BevelPanel.AdvancedTab tab = sender as BevelPanel.AdvancedTab;
            this.labelNumber.Text = tab.TabNumber.ToString();
            this.labelStatus.Text = tab.Name + " click";
            this.advancedTabPanel1.TabActive = tab.TabNumber;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.labelStatus.Text = "We wish you happy advanced tab panel usage !";
            this.advancedTabPanel1.Tabs[0].TabColorUnselected = Color.Red;
            this.advancedTabPanel1.Tabs[1].TabColorUnselected = Color.Yellow;
            this.advancedTabPanel1.Tabs[2].TabColorUnselected = Color.Lime;
            this.advancedTabPanel1.Tabs[3].TabColorUnselected = Color.Pink;
            this.advancedTabPanel1.Tabs[0].RotatedTextAngle = -5;
            this.advancedTabPanel1.Tabs[1].RotatedTextAngle = 10;
            this.advancedTabPanel1.Tabs[2].RotatedTextAngle = -10;
        }

        private void buttonExit_Click(object sender, EventArgs e)
        {
            // Exit button.
            foreach (var tabpanel in this.advancedTabPanel1.Tabs)
            {
                // Remove event handler from all tabs.
                tabpanel.Click -= this.TabClick;
            }

            this.Close();
        }
    }
}

 

Points of Interest

You might also like to use rounded buttons, see article here.

I noticed too late that only the main form project was set to .NET 4 and the rest was still set to .NET 3.5, if it bothers you just change all projects to the version of your choice.

Note: AdvancedTabPanel sadly has no full designer support for placing controls on the tab pages and switching between them, this has to be done programmatically. I tried to get tab page serialization working in the designer, but only got errors, if someone manages to accomplish this feat, I would like to hear ASAP!

History

  • V 1.0
  • V 2.0 new
  • Simplified usage, no need to change the parent property of controls
  • The tab page can now be changed in the designer with the TabActive property, new controls will be Tagged with the chosen tab number
  • Fixed the AdvancedTabPanel gradient mode and styles, if BackColor is not transparent the styles will be applied
  • When the tab color has been changed, keep the changes
     

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)