カスタマイズ可能な TabControl

昨今はタブベースなアプリケーションへの需要が増しているので,何らかのデスクトップ・アプリケーションを作る際にもタブ化が課題となってきます.これが .NetFramework の場合,WPF を使用すれば問題とならないようなのですが System.Windows.Forms.TabControl を使用すると,背景色が透過にならず SystemColor.Control で固定されてしまう,ヘッダ部分がほとんど変更できないなどアプリケーションの外観を変える際に問題となります(特に,背景を透過指定できず色も固定なのが辛い).

この問題への対策としては,TabControl を継承したクラスを作成して ControlStyles.UserPaint を有効にし,描画部分を自力で描いてしまうと言うものがあります(参考:TabControlのタブが横にあると正常に表示されない: .NET Tips: C#, VB.NET).ただ,いったん ControlStyles.UserPaint を有効にしてしまうと,タブのヘッダ部分などを全て自力で描画しなければならず,システムで用意されてあるレベルまで持っていくのはかなり大変です.

そんな訳で,カスタマイズ可能な TabControl をいろいろ探していたのですが,以下のプロジェクトがかなり完成度が高く良い感じでした.

このプロジェクトページにあるデモプロジェクトをビルドして実行した結果が以下の画像になります.

CustomTabControl では,

  • None
  • Default
  • VisualStudio
  • Rounded
  • Angled
  • Chrome
  • IE8
  • VS2010

の 7種(+ 表示させない)の外観が用意されており,Default 以降のそれぞれの項目が画像の各タブの見た目に対応しています(これらは, DispalyStyle プロパティで変更する事ができる).外観は,DisplayStyleProvider プロパティの各メンバを設定する事によりある程度変更する事ができます.

標準にはない「閉じる」ボタン(各タブの右側に表示されている×ボタン)も用意されており,よく見られるタブ型アプリケーションと同様のインターフェースを確保できるようになっています(「閉じる」ボタンを表示させるかどうかは,DisplayStyleProvider.ShowTabCloser プロパティで設定可能).尚,デフォルトでは全てのタブが消せるようになっているのですが,全てのタブを消してしまうと TabControl 自体が見えなくなってしまい都合が悪いので,TabClosing イベントに以下のようなイベントハンドラを指定しておくと良いかなと思いました.

// タブが 1個しか開かれていない場合は「閉じる」イベントをキャンセル
private void CustomTabControl_TabClosing(object sender, TabControlCancelEventArgs e) {
    var control = (CustomTabControl)sender;
    if (control.TabCount <= 1) e.Cancel = true;
}

System.Windows.TabControl を(完全に自力描画で)カスタマイズするのは難しいようで,これまであまり良いものに出会えなかったのですが,これでだいぶ楽に実装できるようになりそうです.