1

I am trying to set DrawMode to OwnerDrawFixeddraw and then draw tab title the same way TabControl does with Normal DrawMode, but DrawString method with default parameters gives different results.

In the example below if text is set to Lorem ipsum it works, but if it's set to digits - it draws outside of tab area. Yet TabControl with Normal DrawMode draws everything correctly, how to do the same manually?

using System.Drawing;
using System.Windows.Forms;

namespace TabWidthIssue
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; // Works fine!
            var text = "1234567890-1234567890-1234567890-1234567890-1234567890-123456789X"; // Does not fit!

            // TabControl with OwnerDrawFixed
            var ownerDrawFixedTabControl = new TabControl()
            {
                DrawMode = TabDrawMode.OwnerDrawFixed,
                Parent = this,
                Dock = DockStyle.Top,
            };

            ownerDrawFixedTabControl.DrawItem += new DrawItemEventHandler(ownerDrawFixedTabControl_DrawItem);

            ownerDrawFixedTabControl.TabPages.Add(new TabPage(text));

            // TabControl with Normal
            var normalTabControl = new TabControl()
            {
                DrawMode = TabDrawMode.Normal,
                Parent = this,
                Dock = DockStyle.Top,
            };

            normalTabControl.TabPages.Add(new TabPage(text));
        }

        void ownerDrawFixedTabControl_DrawItem(object sender, DrawItemEventArgs e)
        {
            var tabControl = sender as TabControl;
            var tabPage = tabControl.TabPages[e.Index];

            var format = new StringFormat
            {
                FormatFlags = StringFormatFlags.NoWrap,
                Trimming = StringTrimming.None
            };

            using (var brush = new SolidBrush(Color.Black))
                e.Graphics.DrawString(tabPage.Text, e.Font, brush, tabControl.GetTabRect(e.Index), format);
        }
    }
}

Example

Update 1 The task of "drawing text" the same way may be replaced by "measuring the text the same way". I know the size of the text I am going to draw (with either DrawString or DrawText) but I need to ensure the tab is wide enough. The width from TextRenderer.MeasureText do no match the actual width of tab created.

Eugene
  • 41
  • 6
  • See [this](http://stackoverflow.com/q/7268238/1997232). – Sinatr Jun 28 '16 at 12:30
  • All the native controls use TextRenderer.DrawText() to render text. It is subtly different from DrawString(). It is otherwise up to you to ensure the tab is wide enough to fit the text, do avoid something as drastically impractical as that string. – Hans Passant Jun 28 '16 at 13:53
  • @HansPassant The width of the tab is calculated automatically based on the text, is there any alternative way to explicitly specify tab width (except for 'ItemSize' property for I need tabs to be of different widths). – Eugene Jul 12 '16 at 12:00

1 Answers1

1

framework uses this

TextRenderer.DrawText(g, tabItemText, font, contentBounds, textColor, flags);
Tom Söhne
  • 512
  • 2
  • 6
  • A little information on the exact `flags` provided to the call might be useful, otherwise +1. – Thorsten Dittmar Jun 28 '16 at 12:59
  • Yes, we can see that in the docs, but you say that the framework uses the call, so it would be important to know the exact combination of values to achieve the same result that the original implementation renders. – Thorsten Dittmar Jun 28 '16 at 13:07
  • Thanks @Tom! But as @ThorstenDittmar mentioned, the exact match is still not achieved, I tried flags `TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine` from [TabRenderer.cs](http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/TabRenderer.cs) but the results are still different. I shall update my post. – Eugene Jul 12 '16 at 12:06
  • @Eugene years later... While I'm still trying to figure out why my `TabControl` is drawing tab text even with `OwnerDrawFixed` (after `DrawItem` is called), I can tell you if you adjust `contentBounds` to be `e.Bounds.Offset(1, 1)` it will draw correctly. – NetMage Aug 30 '19 at 22:56