OC_
OC_

Reputation: 446

Recoloring TabControl

I have a tab control which I want to customize. To be more specific, I want to change the color of the tab page header, as well as the color of that white line around the tab page (check first picture).

I thought of using a custom renderer to do this (similar to recoloring a menu strip, for example), but I'm not sure how to do this. I've also read that setting the DrawMode to OwnerDrawFixed may do this, but using this option makes the the tab control look as if my program was made in the '90s (check second picture).

What I really want to do is to keep the tabs simple and flat and change their color. Check the way tabs are in Visual Studio as an example (check third picture).

enter image description here

Any ideas?

Edit: Another picture of the tab page so that it's more clear what this "white line" is.

enter image description here

Upvotes: 2

Views: 4073

Answers (1)

When you use OwnerDrawFixed it means you will supply the drawing code. If you did not hook up and use the DrawItem event, nothing gets drawn. This will look much the same as yours at design time, because the event is not firing. For design time painting, you'd have to subclass the control and use OnDrawItem.

   // colors to use
   private Color[] TColors = {Color.Salmon, Color.White, Color.LightBlue};

   private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
   {
       // get ref to this page
       TabPage tp = ((TabControl)sender).TabPages[e.Index];

       using (Brush br = new SolidBrush(TColors[e.Index]))
       {
           Rectangle rect = e.Bounds;
           e.Graphics.FillRectangle(br, e.Bounds);

           rect.Offset(1, 1);
           TextRenderer.DrawText(e.Graphics, tp.Text, 
                  tp.Font, rect, tp.ForeColor);

           // draw the border
           rect = e.Bounds;
           rect.Offset(0, 1);
           rect.Inflate(0, -1);

           // ControlDark looks right for the border
           using (Pen p = new Pen(SystemColors.ControlDark))
           {
               e.Graphics.DrawRectangle(p, rect);
           }

           if (e.State == DrawItemState.Selected) e.DrawFocusRectangle();
        }
   }

basic result:

enter image description here

The tab thumb looks a bit cramped to me and not as tall as the default. So, I added a TFontSize to draw the text at a different size than the Font.

Set the TabControl.Font to 10 (which seems to be plenty), so that Windows draws a slightly larger thumb/header. If you still draw the text at the default 8.25, there is more room:

   private float TFontSize = 8.25F;       // font drawing size
   ...
   using (Font f = new Font(tp.Font.FontFamily,TFontSize))
   {
       // shift for a gutter/padding
       rect.Offset(1, 1);                  
       TextRenderer.DrawText(e.Graphics, tp.Text, 
                     f, rect,  tp.ForeColor);
   }

enter image description here

One thing you will loose this way is the VisualStyles effect, but they would seem to clash with colored tabs anyway.

Upvotes: 3

Related Questions