1

I am having some issues rotating the text on a tab. The tabs originally worked just fine, but then I wanted to bold the text when selected, so I used the Draw Item Event. I added a RotateTransform and a TranslateTransform, but its not working. The text just doesn't show up. I have troubleshot it and if I take the rotation away, the text is visible, but when I use the rotate to make the text vertical, it disappears. Here's my code:

    private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
    {
        Graphics g = e.Graphics;
        string tabText = tabControl1.TabPages[e.Index].Text;
        SizeF textSize = g.MeasureString(tabText, tabControl1.Font);
        Brush _textBrush = Brushes.Black;
        TabPage _tabPage = tabControl1.TabPages[e.Index];
        System.Drawing.Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
        StringFormat _stringFlags = new StringFormat();
        _stringFlags.Alignment = StringAlignment.Center;
        _stringFlags.LineAlignment = StringAlignment.Center; 

        PointF tabPt = new PointF(_tabBounds.Left+(_tabBounds.Width), _tabBounds.Top+(_tabBounds.Height));

        if (e.Index == tabControl1.SelectedIndex)
        {
            g.RotateTransform(-90);
            g.TranslateTransform(tabPt.X, tabPt.Y);

            g.DrawString(tabControl1.TabPages[e.Index].Text,
                new Font(tabControl1.Font, FontStyle.Bold),
                _textBrush,
                new PointF(tabPt.X, tabPt.Y));
            g.ResetTransform();
        }
        else
        {
            g.TranslateTransform(tabPt.X, tabPt.Y);                
           g.RotateTransform(-90);

            g.DrawString(tabControl1.TabPages[e.Index].Text,
                tabControl1.Font,
                _textBrush,
                new PointF(tabPt.X,tabPt.Y));
            g.ResetTransform();
        }
    }
}

Any help would be greatly appreciated.

EDIT Here's the image:

enter image description here

Here's the new code:

        Graphics g = e.Graphics;
        string tabText = tabControl1.TabPages[e.Index].Text;
        SizeF textSize = g.MeasureString(tabText, tabControl1.Font);
        Brush _textBrush = Brushes.Black;
        TabPage _tabPage = tabControl1.TabPages[e.Index];
        System.Drawing.Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
        PointF rotPt = new PointF(_tabBounds.Left + (_tabBounds.Width / 2) - (2.75F), _tabBounds.Top + (_tabBounds.Height / 2) + (textSize.Width/2));
        PointF tabPt = new PointF(_tabBounds.Left + (_tabBounds.Width / 2) - (2.75F), _tabBounds.Top + (_tabBounds.Height / 2) + (textSize.Width)/2);
        if (e.Index == tabControl1.SelectedIndex)
        {
            g.TranslateTransform(rotPt.X, rotPt.Y);
            g.RotateTransform(-90);
            g.TranslateTransform(-(rotPt.X), -(rotPt.Y));

            g.DrawString(tabText,
                new Font(tabControl1.Font, FontStyle.Bold),
                _textBrush,
                new PointF(rotPt.X, rotPt.Y));
        }
        else
        {
            g.TranslateTransform(rotPt.X, rotPt.Y);
            g.RotateTransform(-90);
            g.TranslateTransform(-rotPt.X, -rotPt.Y);

            g.DrawString(tabText,
                tabControl1.Font,
                _textBrush,
                new PointF(rotPt.X,rotPt.Y));
        }
akb
  • 43
  • 7
  • The rotation point is probably off! this is tricky to get right. Test with a small angle like 1-5 degrees! – TaW Feb 25 '16 at 23:15
  • Do you have any insight on how exactly the rotation point is calculated? It doesn't appear to be the point loaded into the TranslateTransform function. – akb Feb 25 '16 at 23:59
  • Sorry I just looked a little closer at your code. You need to do this: translate, rotate, translate back, drawstring! adding a trackbar help a lot when testing!! – TaW Feb 26 '16 at 00:27
  • Thanks for the reply! I changed it to this, but now the rotation is gone. – akb Feb 26 '16 at 02:42
  • g.TranslateTransform(rotPt.X, rotPt.Y); g.RotateTransform(-90); g.ResetTransform(); g.DrawString(tabControl1.TabPages[e.Index].Text, new Font(tabControl1.Font, FontStyle.Bold), _textBrush, new PointF(tabPt.X, tabPt.Y)); – akb Feb 26 '16 at 02:43
  • No 'Translate back' meant someting like Translate(-rotPt.X, -rotPt.Y). A ResetTransform is only needed if you draw more unrotated stuff after the rotated text. As you don't you can omit it - each tab will get a fresh graphics instance.. – TaW Feb 26 '16 at 03:47
  • It worked! Thanks so much! I'll post my code after I tweak it a little bit. Thanks again – akb Feb 26 '16 at 17:31
  • One more issue. The text is being written twice. I'll edit my post so you can see. – akb Feb 26 '16 at 19:39
  • this looks weird! are there more than the 6 tabs? i can't understand how one drawstring can do that nor how it can draw outside of the tab bounds.. try using two brushes with different colors to see if they all follow.. btw I would use the `e.Bounds` instead of the `GetTabRect;` I would also use `e.State.HasFlag(DrawItemState.Selected)`instead of `tabControl1.SelectedIndex`.. Finally: It looks as if the extra strings are rotated another -90 degrees. So maybe adding a `ResetTransform` is a good idea after all..?? – TaW Feb 26 '16 at 20:11
  • That did it! Thanks again. I'll post the final code. – akb Feb 26 '16 at 21:05

1 Answers1

1

Thanks TaW for your help. Here's the final code and its working.

   public form1()
    {
        InitializeComponent();            
        tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
        tabControl1.DrawItem += new DrawItemEventHandler(tabControl1_DrawItem);
    }

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)

    {
        Graphics g = e.Graphics;
        string tabText = tabControl1.TabPages[e.Index].Text;
        SizeF textSize = g.MeasureString(tabText, tabControl1.Font);
        Brush _textBrush = Brushes.Black;
        TabPage _tabPage = tabControl1.TabPages[e.Index];
        System.Drawing.Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
        PointF rotPt = new PointF(_tabBounds.Left + (_tabBounds.Width / 2) - (textSize.Height / 2), _tabBounds.Top + (_tabBounds.Height / 2) + (textSize.Width/2));

        if (e.State.HasFlag(DrawItemState.Selected))
        {
            g.TranslateTransform(rotPt.X, rotPt.Y);
            g.RotateTransform(-90);
            g.TranslateTransform(-(rotPt.X), -(rotPt.Y));

            g.DrawString(tabText,
                new Font(tabControl1.Font, FontStyle.Bold),
                _textBrush,
                new PointF(rotPt.X, rotPt.Y));
            g.ResetTransform();
        }

        else
        {
            g.TranslateTransform(rotPt.X, rotPt.Y);
            g.RotateTransform(-90);
            g.TranslateTransform(-rotPt.X, -rotPt.Y);

            g.DrawString(tabText,
                tabControl1.Font,
                _textBrush,
                new PointF(rotPt.X,rotPt.Y));
            g.ResetTransform();
        }
    }

P.S. I never did get the e.Bounds rather than GetTabRect (i'm not sure how to set it to the selected tab).

akb
  • 43
  • 7