C#でTabControlのタブ札をOnPaint()をオーバーライドして独自描画してみたッス。

ダーク

ダーク

上図はタブコントロールの描画結果の例です。

ソースは以下。


using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace UserClass
{
    public class MyCustompaintTabControl : TabControl
    {
        public MyCustompaintTabControl() : base()
        {
            this.SizeMode = TabSizeMode.Normal;

        }

        private Color hilightForeClolor = Color.Black;
        private Color hilightBackColor = Color.Pink;
        private Color noneHilightForeColor = Color.Black;
        private Color noneHilightBackColor = Color.LavenderBlush;
        private Color boarderColor = Color.DeepPink;
        private Color clientBackColor = Color.LightPink;
        private Color backColor = Color.DeepPink;
        public Color HilightForeColor
        {
            get
            {
                return this.hilightForeClolor;
            }
            set
            {
                this.hilightForeClolor = value;
            }
        }
        public Color HilightBackColor
        {
            get
            {
                return this.hilightBackColor;
            }
            set
            {
                this.hilightBackColor = value;
            }
        }
        public Color NoneHilightForeColor
        {
            get
            {
                return this.noneHilightForeColor;
            }
            set
            {
                this.noneHilightForeColor = value;
            }
        }
        public Color NoneHilightBackColor
        {
            get
            {
                return this.noneHilightBackColor;
            }
            set
            {
                this.noneHilightBackColor = value;
            }
        }
        public Color ClientBackColor
        {
            get
            {
                return this.clientBackColor;
            }
            set
            {
                this.clientBackColor = value;
            }
        }
        public override Color BackColor
        {
            get
            {
                return this.backColor;
            }
            set
            {
                this.backColor = value;
            }
        }

        private bool isDoCustomPaint = false;
        public bool IsDoCustomPaint
        {
            get
            {
                return this.isDoCustomPaint;
            }
            set
            {
                this.isDoCustomPaint = value;

                if (this.isDoCustomPaint)
                {
                    this.SetStyle(
                        ControlStyles.UserPaint |
                        ControlStyles.OptimizedDoubleBuffer |
                        ControlStyles.Opaque |
                        ControlStyles.AllPaintingInWmPaint |
                        ControlStyles.ResizeRedraw, true);
                }
                else
                {
                    this.SetStyle(ControlStyles.UserPaint, false);
                    //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
                    this.SetStyle(ControlStyles.Opaque, false);
                    this.SetStyle(ControlStyles.AllPaintingInWmPaint, false);
                    //this.SetStyle(ControlStyles.ResizeRedraw, false);

                }
            }
        }

        //  参考URL:http://www.sakai.zaq.ne.jp/script/cs/tabcontrol/cs_tabcontrol_004.html
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.isDoCustomPaint && this.TabPages.Count != 0)
            {
                Brush hilightForeBrush = new SolidBrush(this.HilightForeColor);
                Brush hilightBackBrush = new SolidBrush(this.HilightBackColor);
                Brush noneHilightForeBrush = new SolidBrush(this.NoneHilightForeColor);
                Brush noneHilightBackBrush = new SolidBrush(this.NoneHilightBackColor);
                Brush clientBrush = new SolidBrush(this.ClientBackColor);
                Brush backBrush = new SolidBrush(this.BackColor);

                Graphics g = e.Graphics;
                Rectangle rect = this.GetTabRect(this.SelectedIndex);
                //g.FillRectangle(Brushes.Pink, this.ClientRectangle);
                //g.FillRectangle(Brushes.DeepPink, 0, 0, this.Width, rect.Height + 2);

                GraphicsPath path1 = new GraphicsPath();
                GraphicsPath path2 = new GraphicsPath();
                path1.AddRectangle(this.ClientRectangle);
                path2.AddRectangle(new Rectangle(this.Left, this.Top, this.Width, this.Height));
                Region r = new System.Drawing.Region(path1);
                r.Union(path2);
                g.FillRegion(Brushes.Black, r);

                Rectangle client = new Rectangle(this.ClientRectangle.X+1, this.ClientRectangle.Y+1, this.ClientRectangle.Width-2, this.ClientRectangle.Height-2);
                g.FillRectangle(clientBrush, client);
                g.FillRectangle(backBrush, 1, 1, this.Width-2, this.Height-2);

                /*
                g.FillRectangle(clientBrush, this.ClientRectangle);
                g.FillRectangle(backBrush, 0, 0, this.Width, rect.Height + 2);
                */

                // タブ描画
                for (int i = 0; i < this.TabCount; i++)
                {
                    TabPage page = this.TabPages[i];
                    Rectangle innerRect = this.GetTabRect(i);
                    Rectangle boarderRect = this.GetTabRect(i);

                    //Brush innerBrush = Brushes.Pink;
                    //Brush boarderBrush = Brushes.Pink;

                    innerRect.Inflate(new Size(-1, -1));
                    int margin = 0;
                    if (0 <= page.ImageIndex)
                    {
                        margin = 16;
                    }
                    // 選択中タブの場合
                    if (i == this.SelectedIndex)
                    {
                        //g.FillRectangle(clientBrush, boarderRect);
                        Rectangle ri = new Rectangle(boarderRect.X, boarderRect.Y, boarderRect.Width, boarderRect.Height-1);
                        g.FillRectangle(Brushes.Black, ri);
                        g.FillRectangle(hilightBackBrush, innerRect);

                        SizeF fontSize = g.MeasureString(this.TabPages[i].Text, this.Font);

                        int marginx = (int)(((double)innerRect.Width - fontSize.Width) / 2);
                        int marginy = (int)((((double)innerRect.Height) - fontSize.Height) / 2);
                        g.DrawString(this.TabPages[i].Text, this.Font, hilightForeBrush, innerRect.X + marginx, innerRect.Y+marginy);

                        // 選択中タブ以外
                    }
                    else
                    {
                        g.FillRectangle(backBrush, boarderRect);

                        Rectangle rectA = this.GetTabRect(i);
                        Rectangle rectB = this.GetTabRect(i);
                        rectA.Height = 10;
                        rectB.Y = rectB.Y + 5;
                        rectB.Height = rectB.Height - 5;

                        rectA.Inflate(-1, -1);
                        rectB.Inflate(-1, -1);

                        /*
                        // -------- 手法テスト1 ----------------
                        g.FillEllipse(noneHilightBackBrush, rectA);
                        g.FillRectangle(noneHilightBackBrush, rectB);
                        //g.FillRectangle(noneHilightBackBrush, innerRect);
                        */

                        // ------- 手法テスト2 -------------
                        /* //http://dobon.net/vb/dotnet/graphics/drawpath.html
                        GraphicsPath myPath = new GraphicsPath();
                        myPath.AddEllipse(rectA);
                        myPath.AddRectangle(rectB);
                        g.FillPath(noneHilightBackBrush, myPath);
                        */

                        // ------- 手法テスト3 -------------
                        //https://msdn.microsoft.com/ja-jp/library/Aa328050(v=VS.71).aspx
                        GraphicsPath myPath = new GraphicsPath();
                        GraphicsPath myPath2 = new GraphicsPath();
                        myPath.AddEllipse(rectA);
                        myPath2.AddRectangle(rectB);
                        Region ri2 = new System.Drawing.Region(myPath);
                        ri2.Union(myPath2);
                        g.FillRegion(Brushes.Black, ri2);

                        rectA.Inflate(-1, -1);
                        rectB.Inflate(-1, -1);
                        GraphicsPath myPath3 = new GraphicsPath();
                        GraphicsPath myPath4 = new GraphicsPath();
                        myPath3.AddEllipse(rectA);
                        myPath4.AddRectangle(rectB);
                        Region r2 = new System.Drawing.Region(myPath3);
                        r2.Union(myPath4);
                        g.FillRegion(noneHilightBackBrush, r2);

                        SizeF fontSize = g.MeasureString(this.TabPages[i].Text, this.Font);
                        int marginx = (int)(((double)innerRect.Width - fontSize.Width) / 2);
                        int marginy = (int)((((double)innerRect.Height) - fontSize.Height) / 2);
                        g.DrawString(this.TabPages[i].Text, this.Font, noneHilightForeBrush, innerRect.X + marginx, innerRect.Y+marginy);
                    }

                    // アイコン描画
                    if (0 <= page.ImageIndex)
                    {
                        g.DrawImage(this.ImageList.Images[page.ImageIndex], innerRect.X, innerRect.Y);
                    }
                }
            }
            base.OnPaint(e);
            //base.OnPaint(e);

        }

        /*
        //  参考URL:http://www.sakai.zaq.ne.jp/script/cs/tabcontrol/cs_tabcontrol_004.html
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this.TabPages.Count != 0)
            {
                Graphics g = e.Graphics;
                Rectangle rect = this.GetTabRect(this.SelectedIndex);
                g.FillRectangle(SystemBrushes.HotTrack, this.ClientRectangle);
                g.FillRectangle(SystemBrushes.Control, 0, 0, this.Width, rect.Height + 2);

                // タブ描画
                for (int i = 0; i < this.TabCount; i++)
                {
                    TabPage page = this.TabPages[i];
                    Rectangle rect2 = this.GetTabRect(i);
                    int margin = 0;
                    if (0 <= page.ImageIndex)
                    {
                        margin = 16;
                    }
                    // 選択中タブの場合
                    if (i == this.SelectedIndex)
                    {
                        g.FillRectangle(SystemBrushes.HotTrack, rect2);
                        g.DrawString(this.TabPages[i].Text, this.Font, SystemBrushes.HighlightText, rect2.X + margin, rect2.Y);

                        // 選択中タブ以外
                    }
                    else
                    {
                        g.FillRectangle(SystemBrushes.Control, rect2);
                        g.DrawString(this.TabPages[i].Text, this.Font, SystemBrushes.WindowText, rect2.X + margin, rect2.Y);
                    }

                    // アイコン描画
                    if (0 <= page.ImageIndex)
                    {
                        g.DrawImage(this.ImageList.Images[page.ImageIndex], rect2.X, rect2.Y);
                    }
                }
            }
            base.OnPaint(e);
            //base.OnPaint(e);

        }
         */

        /*
        protected override void OnPaint(PaintEventArgs e)
        {
            //対象のTabControlを取得
            TabControl tab = this;

            // --- 実験:クライアント領域を黒でべた塗りする ---
            Brush o = Brushes.Black;
            e.Graphics.FillRectangle(o, tab.ClientRectangle);

            foreach (TabPage page in this.TabPages)
            {
                //タブページのテキストを取得
                string txt = page.Text;

                //タブのテキストと背景を描画するためのブラシを決定する
                Brush foreBrush, backBrush;
                if (page.Equals(tab.SelectedTab))
                {
                    //選択されているタブのテキストを赤、背景を青とする
                    foreBrush = Brushes.White;
                    backBrush = Brushes.DarkGray;
                }
                else
                {
                    //選択されていないタブのテキストは灰色、背景を白とする
                    foreBrush = Brushes.Pink;
                    backBrush = Brushes.DeepPink;
                }

                //StringFormatを作成
                StringFormat sf = new StringFormat();
                //中央に表示する
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;

                //背景の描画
                e.Graphics.FillRectangle(backBrush, page.Bounds);
                //Textの描画
                e.Graphics.DrawString(txt, page.Font, foreBrush, page.Bounds, sf);
            }
        }
         * */
    }
}