Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations sizbut on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Set color and fontstyle of a TabPage title

Status
Not open for further replies.

polocar

Programmer
Sep 20, 2004
89
IT
Hello,
I'm writing a program in Visual C# using Visual Studio .NET Professional 2003.

In the main form I have placed a TabControl control with 3 TabPages controls.
I would like that, when a tabpage was selected (with a mouse click or the right arrow key pressed), its title changed color (from black to blue, i.e.) and became bold, to distinguish the selected page from the others (so, when I change page, I also have to switch the previously selected page title from blue to black and from bold to regular).

I thought to organize the code in the way I reported below: my problem is that I don't know how to set the color and the fontstyle of a tabpage title (it would be possible however... or not???).

There is also another strange thing: the program doesn't execute the tabPageOnGotFocus event handler (when I select a tabpage, the statement contained in the event handler

tabPageSelectedTab.Text = "selected";

isn't executed).
I have put a breakpoint too, but the program doesn't stop.

Have I made any errors?
Thank you very much (here is the code)

Code:
using System;
using System.Drawing;
using System.Windows.Forms;

class MainForm: Form
{
	private TabControl tabControl1;
	private TabPage tabPage1, tabPage2, tabPage3;

	private TabPage tabPageSelectedTab, tabPageOldSelectedTab;

	public static void Main()
	{
		Application.Run(new MainForm());
	}

	public MainForm()
	{
		tabControl1 = new TabControl();
		tabPage1 = new TabPage();
		tabPage2 = new TabPage();
		tabPage3 = new TabPage();

		Controls.Add(tabControl1);
		tabControl1.Controls.Add(tabPage1);
		tabControl1.Controls.Add(tabPage2);
		tabControl1.Controls.Add(tabPage3);

		tabPage1.Text = "Page 1";
		tabPage1.GotFocus += new EventHandler(tabPageOnGotFocus);

		tabPage2.Text = "Page 2";
		tabPage2.GotFocus += new EventHandler(tabPageOnGotFocus);

		tabPage3.Text = "Page 3";
		tabPage3.GotFocus += new EventHandler(tabPageOnGotFocus);

		tabControl1.SelectedTab = tabPage1;
		tabPageSelectedTab = tabPage1;
		tabPageOldSelectedTab = tabPage1;
	}

	void tabPageOnGotFocus(object obj, EventArgs ea)
	{
		tabPageOldSelectedTab = tabPageSelectedTab;
		tabPageSelectedTab = (TabPage)obj;

		// code for changing old selected tabpage title from blue
		// to black color and from bold to regular fontstyle

		// tabPageOldSelectedTab... (???)

		// code for changing selected tabpage title from black
		// to blue color and from regular to bold fontstyle

		// tabPageSelectedTab... (???)

		tabPageSelectedTab.Text = "selected";
	}
}
 
Well, it is not so simple.
First of all, the event you need to catch is "SelectedIndexChanged".
Second, the font property of a tab page affect only the controls in the tab, but the tab header is part of the tab control, not the page.
The TabControl of Microsoft is simple and don't expose the header style, but you can draw it yourself.
Here is a sample:
Code:
		private void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			Graphics g = tabControl1.CreateGraphics();
			Rectangle rect = new Rectangle(tabControl1.SelectedIndex * tabControl1.ItemSize.Width + 2, 2, tabControl1.ItemSize.Width - 2, tabControl1.ItemSize.Height - 2);
			g.FillRectangle(Brushes.LightBlue, rect);
			g.DrawString(tabControl1.SelectedTab.Text, new Font(tabControl1.SelectedTab.Font, FontStyle.Bold), Brushes.Black, rect);
		}
The problem is that the the rectangle you fill cover the header, so you need to draw it yourself. You don't need to erase the back color after selecting another tab, because it being painted again.
 
Hi Korach,
that's a good idea.
I examined in the MSDN library the properties you have used, and I have another question for you:
is there a way to adapt your code to the case in which the tab headers have different sizes? (unfortunately it's my situation, because the first header text is very short and the second very long, so it would be good that the tab headers were dimensioned accordingly...)

Thank you
 
I didn't find any way to know the header sizes.
I suggest you do one of these:
1. Set the SizeMode Property of the TabControl to Fixed, and Set the ItemSize.Width to the longest header size.
2. Calculate the headers text width. You can do it by creating a label control in runtime and set its text to the header text, and set the property AutoSize to true. The width of the label will be similar to the header width. you need to iterate through the pages and calculate the headers width.

You need to do complicated things with the tab control, but Microsoft controls are very simple. Try to look for a custom tab control in the internet.
I have a great one but it costs 500$ (a package of hundreds controls).
 
Found something.
You can use Graphics.MeasureString and TabControl.Padding to calculate the tab header place.
Code:
			Graphics g = tabControl1.CreateGraphics();
			int TabsWidth = 0;
			int pad = tabControl1.Padding.X;
			for (int i=0; i<tabControl1.SelectedIndex ; i++)
			{
				TabsWidth += (int)g.MeasureString(tabControl1.TabPages[i].Text, tabControl1.Font).Width + pad;
			}

			TabsWidth += pad;
			Rectangle rect = new Rectangle(TabsWidth, tabControl1.Padding.Y, (int)g.MeasureString(tabControl1.SelectedTab.Text, tabControl1.Font).Width, (int)g.MeasureString(tabControl1.SelectedTab.Text, tabControl1.Font).Height + tabControl1.Padding.Y);
			g.FillRectangle(Brushes.LightBlue, rect);
			g.DrawString(tabControl1.SelectedTab.Text, new Font(tabControl1.SelectedTab.Font, FontStyle.Bold), Brushes.Black, rect);
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top