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

ダーク

ダーク

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

ソースは以下。

[csharp]

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);
}
}
* */
}
}

[/csharp]