タブコントロールのタブをオーナードローする(自分で描画する)方法を紹介します。
タブコントロールのDrawModeプロパティをTabDrawMode.OwnerDrawFixedとすると、DrawItemイベントハンドラでタブを描画できるようになります。
次の例では、フォームにタブコントロールTabControl1があり、そのTabControl1をオーナードローすることにより、テキストを中央表示し、さらに、選択されているタブのテキストが赤、背景が青、選択されていないタブのテキストが灰色、背景が白となるようにしています。
また、この例ではSizeModeプロパティをTabSizeMode.Fixedにすることで、タブのサイズを固定しています。このようにしなくても大丈夫ですが、タブの大きさが勝手に調整されてしまうと、文字列が思ったように表示できない場合があります。
'フォームのLoadイベントハンドラ Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles MyBase.Load 'タブのサイズを固定する TabControl1.SizeMode = TabSizeMode.Fixed TabControl1.ItemSize = New Size(60, 18) 'TabControlをオーナードローする TabControl1.DrawMode = TabDrawMode.OwnerDrawFixed End Sub 'TabControl1のDrawItemイベントハンドラ Private Sub TabControl1_DrawItem(ByVal sender As Object, _ ByVal e As DrawItemEventArgs) _ Handles TabControl1.DrawItem '対象のTabControlを取得 Dim tab As TabControl = CType(sender, TabControl) 'タブページのテキストを取得 Dim txt As String = tab.TabPages(e.Index).Text 'タブのテキストと背景を描画するためのブラシを決定する Dim foreBrush, backBrush As Brush If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then '選択されているタブのテキストを赤、背景を青とする foreBrush = Brushes.Red backBrush = Brushes.Blue Else '選択されていないタブのテキストは灰色、背景を白とする foreBrush = Brushes.Gray backBrush = Brushes.White End If 'StringFormatを作成 Dim sf As New StringFormat '中央に表示する sf.Alignment = StringAlignment.Center sf.LineAlignment = StringAlignment.Center '背景の描画 e.Graphics.FillRectangle(backBrush, e.Bounds) 'Textの描画 e.Graphics.DrawString(txt, e.Font, foreBrush, RectangleF.op_Implicit(e.Bounds), sf) End Sub
//フォームのLoadイベントハンドラ private void Form1_Load(object sender, System.EventArgs e) { //タブのサイズを固定する TabControl1.SizeMode = TabSizeMode.Fixed; TabControl1.ItemSize = new Size(60, 18); //TabControlをオーナードローする TabControl1.DrawMode = TabDrawMode.OwnerDrawFixed; //DrawItemイベントハンドラを追加 TabControl1.DrawItem += new DrawItemEventHandler(TabControl1_DrawItem); } //TabControl1のDrawItemイベントハンドラ private void TabControl1_DrawItem(object sender, DrawItemEventArgs e) { //対象のTabControlを取得 TabControl tab = (TabControl)sender; //タブページのテキストを取得 string txt = tab.TabPages[e.Index].Text; //タブのテキストと背景を描画するためのブラシを決定する Brush foreBrush, backBrush; if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { //選択されているタブのテキストを赤、背景を青とする foreBrush = Brushes.Red; backBrush = Brushes.Blue; } else { //選択されていないタブのテキストは灰色、背景を白とする foreBrush = Brushes.Gray; backBrush = Brushes.White; } //StringFormatを作成 StringFormat sf = new StringFormat(); //中央に表示する sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; //背景の描画 e.Graphics.FillRectangle(backBrush, e.Bounds); //Textの描画 e.Graphics.DrawString(txt, e.Font, foreBrush, e.Bounds, sf); }
補足:ホットトラックについて補足します。TabControl.HotTrackプロパティをTrueにしてホットトラック(タブの上にマウスポインタがあるときに外観が変化する)を有効にしても、DrawItemイベントハンドラのDrawItemEventArgs.Stateでタブがホットトラッキング中かを知ることができません(DrawItemEventArgs.StateにDrawItemState.HotLightが含まれません)。DrawItemイベントハンドラ内で、TabControl.GetTabRectメソッドで取得できるタブの範囲内にマウスポインタがあるかを調べることで、タブがホットトラッキング中かを知ることができそうですが、うまくいきません。(私が試してみた限りでは、タブが上か左にある時はうまくいくのですが、タブが下か右にあるときはホットトラッキングが解除されないときがあります。)これは、TabControlのMouseMoveとMouseLeaveイベントハンドラ内でホットトラッキング中のタブを調べることで、改善されるようです。
上記のDrawItemイベントによる方法では、TabControlの背景(上の図で言えば、「最後」のタブの右側の部分)や、タブの枠は自分で描画できません。これらすべてを描画するには、非常に面倒ですが、Paintイベントを発生させて描画する方法があります。この方法について詳しくは、「TabControlを自分でビジュアルスタイルで描画する」をご覧ください。