記事内にはプロモーションが含まれています

【C#】TabControlの使い方とデザインカスタマイズ!切り替えイベントや非表示設定も解説

【C#】TabControlの使い方とデザインカスタマイズ!切り替えイベントや非表示設定も解説 C#

C#のWindowsフォームアプリケーション開発において、限られた画面スペースを有効活用するために欠かせないのが「TabControl(タブコントロール)」です。

設定画面やブラウザのように、カテゴリごとにページを切り替えて表示するUIは、ユーザーにとっても馴染み深く使いやすいものです。

しかし、標準のTabControlを使っていると「タブの色を変えたいのにプロパティがない」「特定のタブだけ一時的に非表示にしたいが、Visibleプロパティが効かない」といった壁にぶつかることがよくあります。

この記事では、TabControlの基本的な使い方から、イベント処理、そして検索ニーズの高い「デザインのカスタマイズ」や「タブの非表示化」といった応用テクニックまで、実務で役立つノウハウを徹底解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

TabControl(タブコントロール)の基本実装

まずは、Visual StudioのツールボックスからTabControlを配置し、基本的な操作を行う方法を見ていきましょう。

フォームデザイナーでの操作だけでなく、コードから動的にタブを操作する方法も知っておくと、アプリケーションの柔軟性が高まります。

フォームへの配置とタブページの追加・削除

TabControlは、その中に複数の「TabPage(タブページ)」を持つコンテナコントロールです。

デザイナー上で「タブの追加」を行うこともできますが、動的にタブを増減させる場合は以下のようにコードを記述します。

using System;
using System.Windows.Forms;

namespace TabControlSample
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            
            // フォームロード時に初期化などを行う
            InitializeTabs();
        }

        private void InitializeTabs()
        {
            // 描画パフォーマンス向上のためレイアウトロジックを一時停止
            this.SuspendLayout();

            // 新しいタブページを作成
            TabPage newPage = new TabPage("新規タブ");
            newPage.Name = "tabPageNew"; // 名前を付けておくと後で検索しやすい
            
            // ボタンなどのコントロールをタブページに追加
            // ★ポイント:フォームではなくTabPageに対してAddする
            Button btn = new Button();
            btn.Text = "ボタン";
            btn.Location = new System.Drawing.Point(10, 10);
            newPage.Controls.Add(btn);

            // TabControlにタブページを追加
            tabControl1.TabPages.Add(newPage);

            // レイアウトロジックを再開
            this.ResumeLayout();
        }

        private void RemoveTab()
        {
            // 名前を指定して削除(推奨)
            // インデックス指定(RemoveAt)は、意図しないタブを消すリスクがあるため注意が必要です
            if (tabControl1.TabPages.ContainsKey("tabPageNew"))
            {
                TabPage targetPage = tabControl1.TabPages["tabPageNew"];
                tabControl1.TabPages.Remove(targetPage);
            }
        }
    }
}

このソースコードでは、TabPage クラスのインスタンスを作成し、それを TabControl.TabPages コレクションに追加(Add)することでタブを増やしています。

逆に削除する場合は Remove メソッドを使用します。

重要なのは、タブの中身(ボタンやテキストボックス)はTabPageコントロールの上に配置するという点です。

フォームに直接置くのではなく、必ず newPage.Controls.Add(btn) のようにタブページに対してコントロールを追加してください。

また、大量のコントロールを配置する場合は、SuspendLayout()ResumeLayout() を挟むことで、追加時の描画チラつきを抑えることができます。

選択されているタブを取得・変更する方法

ユーザーが現在どのタブを見ているかを取得したり、プログラム側から特定のタブに切り替えたりするには、SelectedIndex または SelectedTab プロパティを使用します。

// インデックス(番号)で指定して切り替え
tabControl1.SelectedIndex = 1; // 2番目のタブを選択(0始まり)

// TabPageオブジェクトを直接指定して切り替え
tabControl1.SelectedTab = tabPage2;

// 現在選択されているタブの情報を取得
string currentTabName = tabControl1.SelectedTab.Text;
int currentIndex = tabControl1.SelectedIndex;

MessageBox.Show($"現在は「{currentTabName}」が選択されています。");

画面遷移や入力チェックのエラー時に、該当するタブを強制的に表示させたい場合などに利用します。

タブ切り替え時のイベント処理

タブが切り替わったタイミングでデータを読み込んだり、画面表示を更新したりしたい場合は、イベントを利用します。

また、特定の条件下でタブの切り替えを「禁止」したい場合も、イベントハンドラで制御します。

SelectedIndexChangedイベントの使い方

タブの切り替えが完了した後に処理を行いたい場合は、SelectedIndexChanged イベントを使います。

これが最も一般的なイベントです。

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
    // 選択されたタブを取得
    TabControl tabCtrl = sender as TabControl;
    TabPage current = tabCtrl.SelectedTab;

    // タブごとの処理分岐
    if (current != null && current.Name == "tabPageSettings")
    {
        Console.WriteLine("設定タブが開かれました。設定値をロードします。");
        // 設定読み込み処理などをここに記述
    }
}

このコードは、タブが切り替わるたびに実行されます。

senderTabControl にキャストすることで、どのタブコントロールでイベントが発生したかを特定し、現在選択されているタブページ (SelectedTab) に応じて処理を分岐させています。

無駄な処理を減らすため、必要なタブが開かれた時だけ重い処理(DB接続など)を実行するといった使い方が効果的です。

選択変更をキャンセルするテクニック

「編集中のデータが保存されていない場合、タブの切り替えを許可したくない」といったケースでは、Selecting または Deselecting イベントを使用します。

これにより、切り替え処理を中断(キャンセル)させることができます。

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
    // 例えば、データが未保存かどうかをチェックするフラグ
    bool isDataDirty = true; 

    // 特定の条件で切り替えをキャンセル
    // e.TabPageは「移動先」のタブを指します
    if (isDataDirty && e.TabPage.Name != "tabPageEdit") 
    {
        DialogResult result = MessageBox.Show(
            "保存されていないデータがあります。移動しますか?", 
            "確認", 
            MessageBoxButtons.YesNo
        );

        if (result == DialogResult.No)
        {
            // タブの切り替えをキャンセルする
            e.Cancel = true; 
        }
    }
}

TabControlCancelEventArgsCancel プロパティを true に設定することで、タブの移動を阻止できます。

ユーザーの誤操作によるデータ損失を防ぐために非常に重要なテクニックです。

タブのデザインや色を変更する方法(オーナードロー)

標準のWindowsフォームのTabControlは、プロパティで「タブの背景色」や「文字色」を簡単に変更することができません。

デザインをカスタマイズするには、「オーナードロー(OwnerDraw)」という手法を使い、描画処理を自分で記述する必要があります。

DrawModeプロパティとDrawItemイベント

まず、TabControlの DrawMode プロパティを TabDrawMode.OwnerDrawFixed に設定します。

これで、タブの描画がデフォルトのOS任せから、プログラマの制御下(DrawItem イベント)に移ります。

背景色や文字色を自由にカスタマイズするコード例

public MainForm()
{
    InitializeComponent();

    // オーナードローを有効にする
    tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
    // タブを描画するイベントを登録
    tabControl1.DrawItem += tabControl1_DrawItem;
}

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    // 対象のタブコントロールとタブページを取得
    TabControl tabCtrl = (TabControl)sender;
    TabPage page = tabCtrl.TabPages[e.Index];
    
    // 描画領域(タブの矩形)を取得
    Rectangle bounds = e.Bounds;

    // ブラシの準備(背景色と文字色)
    Brush backBrush;
    Brush foreBrush;

    // 選択されているタブかどうかで色を変える
    if (e.Index == tabCtrl.SelectedIndex)
    {
        // 選択時:青背景に白文字
        backBrush = new SolidBrush(Color.DodgerBlue);
        foreBrush = new SolidBrush(Color.White);
    }
    else
    {
        // 非選択時:グレー背景に黒文字
        backBrush = new SolidBrush(Color.LightGray);
        foreBrush = new SolidBrush(Color.Black);
    }

    // 1. 背景を塗りつぶす
    e.Graphics.FillRectangle(backBrush, bounds);

    // 2. 文字を描画する
    // 文字列の配置(上下左右中央揃え)
    StringFormat stringFormat = new StringFormat();
    stringFormat.Alignment = StringAlignment.Center;
    stringFormat.LineAlignment = StringAlignment.Center;

    e.Graphics.DrawString(
        page.Text, 
        tabCtrl.Font, 
        foreBrush, 
        bounds, 
        stringFormat
    );

    // リソースの解放
    backBrush.Dispose();
    foreBrush.Dispose();
}

このコードを実行すると、選択されているタブが青色、それ以外がグレーで表示されるようになります。

e.Graphics オブジェクトを使って、四角形(背景)を塗りつぶし、その上に文字を描画しています。

OSのテーマによっては、タブの周囲に不要な余白ができる場合があります。
その際は TabControl.Padding プロパティを調整したり、描画領域(bounds)を少し広めに塗るなどの微調整を行ってください。

特定のタブを非表示にする・隠すテクニック

TabControlには、各TabPageの Visible プロパティを false にしても、タブ(つまみ部分)自体は消えないという仕様があります。

特定のタブをユーザーから見えなくするには、TabControlの TabPages コレクションからそのページを一時的に削除(Remove)する必要があります。

TabPages.Removeによる非表示と再表示

タブを非表示にする(削除する)と、そのタブページへの参照や「元の位置」を見失ってしまう可能性があります。

そのため、非表示にする前に Dictionary などを使って情報を保持しておくことが重要です。

using System.Collections.Generic;

// タブとその元のインデックスを保持する辞書
private Dictionary<TabPage, int> hiddenTabs = new Dictionary<TabPage, int>();

// タブを非表示にするメソッド
private void HideTab(TabPage page)
{
    // すでにTabControlにある場合のみ処理
    if (tabControl1.TabPages.Contains(page))
    {
        // 現在のインデックスを保存してから削除
        int index = tabControl1.TabPages.IndexOf(page);
        
        // 辞書に保存(既に隠されている場合は更新しない)
        if (!hiddenTabs.ContainsKey(page))
        {
            hiddenTabs[page] = index;
        }

        tabControl1.TabPages.Remove(page);
    }
}

// タブを再表示するメソッド
private void ShowTab(TabPage page)
{
    // 退避辞書に含まれている場合のみ処理
    if (hiddenTabs.ContainsKey(page))
    {
        int originalIndex = hiddenTabs[page];
        
        // 元のインデックスが現在のタブ数を超えないように調整(安全策)
        // ※他のタブが削除されている可能性があるため
        if (originalIndex > tabControl1.TabCount)
        {
            originalIndex = tabControl1.TabCount;
        }

        // 指定位置に挿入
        tabControl1.TabPages.Insert(originalIndex, page);
        
        // 辞書から削除
        hiddenTabs.Remove(page);
    }
}

このロジックを使用することで、見た目上「タブの表示・非表示」を切り替えることができます。

「管理者権限があるユーザーにだけ設定タブを表示する」といった機能を実装する際に非常に役立ちます。

削除前にインデックスを記録し、Insert メソッドを使って復帰させることで、元の順番を保ったまま再表示が可能です。

C#のスキルを活かして年収を上げる方法

以上、C#でのTabControlの使い方やデザインカスタマイズなどについて解説してきました。

なお、C#のスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

業務システム開発やアプリ開発、ゲーム開発において需要の高いC#を扱えるエンジニアは、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなC#の案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。

C#
スポンサーリンク
code-izumiをフォローする