Tim Van Wassenhove

Passionate geek, interested in Technology. Proud father of two

06 Jan 2007

Enable and disable TabPages on a TabControl

screenshot of tabcontrol with disabled tabpages

screenshot of tabcontrol with disabled tabpages

Apparently Microsoft choose not to implement support for disabled TabPages. The reason seems to be that it’s against their Guidelines for Tabs. Let’s ignore the guideline and implement the support anyway. First we set the DrawMode property of the TabControl to OwnerDrawFixed. Next we add an eventhandler for the DrawItem Event

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
	TabControl tabControl = sender as TabControl;
	TabPage tabPage = tabControl.TabPages[e.Index];
	Rectangle tabRectangle = tabControl.GetTabRect(e.Index);

	if (tabControl.Alignment == TabAlignment.Left || tabControl.Alignment == TabAlignment.Right)
	{
		float rotateAngle = 90;
		if (tabControl.Alignment == TabAlignment.Left)
		{
			rotateAngle = 270;
		}

		PointF cp = new PointF(tabRectangle.Left + (tabRectangle.Width / 2), tabRectangle.Top + (tabRectangle.Height / 2));
		e.Graphics.TranslateTransform(cp.X, cp.Y);
		e.Graphics.RotateTransform(rotateAngle);
		tabRectangle = new Rectangle(-(tabRectangle.Height / 2), -(tabRectangle.Width / 2), tabRectangle.Height, tabRectangle.Width);
	}

	using (SolidBrush foreBrush = new SolidBrush(tabPage.ForeColor))
	{
		using (SolidBrush backBrush = new SolidBrush(tabPage.BackColor))
		{
			if (!tabPage.Enabled)
			{
				foreBrush.Color = SystemColors.GrayText;
			}

			e.Graphics.FillRectangle(backBrush, tabRectangle);

			using (StringFormat stringFormat = new StringFormat())
			{
				stringFormat.Alignment = StringAlignment.Center;
				stringFormat.LineAlignment = StringAlignment.Center;
				e.Graphics.DrawString(tabPage.Text, e.Font, foreBrush, tabRectangle, stringFormat);
			}
		}
	}

	e.Graphics.ResetTransform();
}

And we handle the Selecting Event as following

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
	if (!e.TabPage.Enabled)
	{
		e.Cancel = true;
	}
}

This works pretty fine, but we still have to make sure that the TabPages are Invalidated when the users changes their Enabled property. We do this by attaching and detaching an eventhandler for their EnabledChanged Event when they’re added and removed.

private void tabControl1_ControlAdded(object sender, ControlEventArgs e)
{
	TabPage tabPage = sender as TabPage;
	if (tabPage != null)
	{
		tabPage.EnabledChanged += new EventHandler(this.tabPage_EnabledChanged);
	}
}

private void tabControl1_ControlRemoved(object sender, ControlEventArgs e)
{
	TabPage tabPage = sender as TabPage;
	if (tabPage != null)
	{
		tabPage.EnabledChanged -= new EventHandler(this.tabPage_EnabledChanged);
	}
}

void tabPage_EnabledChanged(object sender, EventArgs e)
{
	TabPage tabPage = sender as TabPage;
	TabControl tabControl = tabPage.Parent as TabControl;
	tabControl.Invalidate(tabPage.ClientRectangle);
}

Feel free to download the demo application: DisabledTabControl.zip.