🗂️

Windows Forms - NavigationView のようなサイドバー形式

に公開

はじめに

UWP - NavigationView は、左端 もしくは 上端にナビゲーションメニューを配置し、選択された項目に応じてメインコンテンツを切り替えることができます。

https://learn.microsoft.com/ja-jp/windows/apps/design/controls/navigationview

WPF では、Nuget - ModernWpfUI を導入することで、NavigationView を利用できます。

https://qiita.com/Kosen-amai/items/f103143c69f7abbdee52

本記事では、Windows Forms で、NavigationView のようなサイドバー形式とする手法について記載します。

テスト環境

ここに記載した情報/ソースコードは、Visual Studio Community 2022 を利用した下記プロジェクトで生成したモジュールを Windows 11 24H2 で動作確認しています。

  • Windows Forms - .NET Framework 4.8
  • Windows Forms - .NET 8

素材

アイコンとして下記を利用させて頂きました。

デザイン

Windows Forms で NavigationView のようなレイアウト実現は、いくつかの手法が存在します。
本記事では、RadioButton と TabControl を用いて、NavigationView のような左端サイドバー形式レイアウトを実現しようと思います。

手順

ベースとなるパネル配置

コンパクトなサンプルとしたいので、フォームサイズを 500, 300 とします。
サイドバー用 Panel - pnlNavigation を追加、Dock = Left として、幅を 150 とします。
次に、コンテンツ用 Panel - pnlContents を追加、Dock = Fill とします。

コンテンツ配置

デザイナ画面で、各コンテンツを編集することを目的に TabControl - tabControl1 を、pnlNavigation に Dock = Fill で配置します。
今回のサンプルにあわせて、タブをひとつ追加した後、それぞのタブに対して Panel を Dock = Fill で追加します。

対象タブ 配置する Panel
tabPage1 pnlUpload
tabPage2 pnlDownload
tabPage3 pnlSettings

それぞれの Panel に対して、パネル切り替えを識別するために Label を追加します。

対象タブ 対象 Panel 配置する Label の Text
tabPage1 pnlUpload UPLOAD コンテンツ
tabPage2 pnlDownload DOWNLOAD コンテンツ
tabPage3 pnlSettings SETTINGS コンテンツ

ナビゲーション配置

RadioButton は単一選択のコントールです。
この単一選択という特性を利用して、ナビゲーションボタンとして下記プロパティで配置します。

  • Appearance = Appearance.Button
  • AutoSize = false
  • FlatStyle = FlatStyle.Flat
  • FlatAppearance.BorderSize = 0
  • Image = <UPLOADアイコン>
  • ImageAlign = ContentAlignment.MiddleLeft
  • Text = UPLOAD
  • TextImageRelation = TextImageRelation.ImageBeforeText
  • Locaion = 0, 0
  • Height = 32
  • Width = 150(pnlNavigation.Width)

コンテンツに対応する RadioButton を配置します。

RadioButton Image Text Location
rbUpload UPLOAD 0, 0
rbDownload DOWNLOAD 0, 32
rbSettings SETTINGS 0, 64

ソースコード

Form1.cs
public partial class Form1 : Form
{
  private List<Panel> lstPanels = new List<Panel>();
  private List<RadioButton> lstNavigate = new List<RadioButton>();

  public Form1()
  {
    InitializeComponent();

    // Panel と RadioButton の関連づけ
    // Navigate2Panel(string keyword)用
    pnlUpload.Tag = rbUpload.Text;
    pnlDownload.Tag = rbDownload.Text;
    pnlSettings.Tag = rbSettings.Text;

    // Panel
    lstPanels.Add(pnlUpload); 
    lstPanels.Add(pnlDownload);
    lstPanels.Add(pnlSettings);
    foreach(var panel  in lstPanels)
    {
      panel.Parent = pnlContents; // pnlContents の子コントールに設定
      // panel.Dock = DockStyle.Fill;   // サンプルではデザイナで設定
    }
    tabControl1.Visible = false;  // TabControl は不要

    // RadioButton
    lstNavigate.Add(rbUpload);
    lstNavigate.Add(rbDownload);
    lstNavigate.Add(rbSettings);
    int height = 32;
    int py = 0;
    foreach(var button in lstNavigate)
    {
      button.CheckedChanged += rbNavigate_CheckChanged;
      button.Location = new Point( 0, py );   // レイアウト再調整
      button.Width = pnlNavigation.Width;     // レイアウト再調整
      button.Height = height;                 // レイアウト再調整
      py += height;
    }

    // 初期選択
    lstNavigate[0].Checked = true;
  }
  // .NET Framework 時 object? の ? 不要
  private void rbNavigate_CheckChanged(object? sender, EventArgs e)
  {
    if (sender is RadioButton button)
    {
      Navigate2Panel(button.Text);
    }
  }
  // Navigate に連動して、対象 Panel を表示
  private void Navigate2Panel(string keyword)
  {
    bool bMatch = false;
    foreach (var panel in lstPanels)
    {
      // keyword に一致するか?
      if (panel.Tag is string tag
       && string.Compare(keyword, tag) == 0)
      {
        panel.Visible = true;
        bMatch = true;
      }
      else
      {
        panel.Visible = false;
      }
    }
    // 一致するモノがない場合は先頭を選択(あり得ないけど...)
    if (!bMatch)
    {
      lstPanels[0].Visible = true;
    }
  }
}

出典

本記事は、2025/05/19 Qiita 投稿記事の転載です。

Windows Forms - NavigationView のようなサイドバー形式

Discussion