はじめに
本記事では、Windows Forms の FolderBrowserDialog における RootFolder プロパティを解説します。RootFolder はダイアログの「ツリーの最上位(どこから辿れるか)」を制御します。SelectedPath(初期選択)や戻り値との関係、よく使う設定例、実務でハマりがちな注意点を、初心者にもわかりやすく整理します。
説明
RootFolder は Environment.SpecialFolder 列挙体で指定し、フォルダ選択ダイアログの「探索可能な範囲の起点」を決めます。既定値は Desktop で、ユーザーはデスクトップ配下(ドライブやユーザーフォルダなどへ)を辿れます。
代表的な値とイメージは以下の通りです。
・Desktop:通常のエクスプローラと同様の起点。最も汎用的。
・MyComputer:PC(このPC)配下が起点。最上位にドライブ(C:\ など)が並ぶ。
・MyDocuments:ドキュメントフォルダをルートに限定。ユーザーデータの保存先を固定したいときに便利。
・UserProfile:ユーザープロファイル(例:C:\Users\ユーザー名)配下に限定。
重要:SelectedPath との関係
表示前に SelectedPath を設定すると、ダイアログの初期展開位置になります。ただし、そのパスは RootFolder の配下である必要があります。配下でない場合、初期展開は無視されたり、RootFolder 直下にフォールバックすることがあります。例えば RootFolder = MyComputer のときは、SelectedPath を C:\(または存在するドライブ)などにしておくのが安全です。
サンプルコード
以下は RootFolder を切り替えながら FolderBrowserDialog を開く最小構成のサンプルです。コンボボックスで RootFolder を選び、必要に応じて初期パス(SelectedPath)を調整してから「参照…」を押します。結果の選択フォルダは下部のテキストボックスに表示します。
using System;
using System.Collections.Generic;
using System.Windows.Forms;
public class MainForm : Form
{
private ComboBox rootCombo;
private TextBox initialPathText;
private TextBox resultText;
private Button browseButton;
// UI表示名と SpecialFolder の対応
private readonly Dictionary<string, Environment.SpecialFolder> rootMap =
new Dictionary<string, Environment.SpecialFolder>
{
{ "Desktop", Environment.SpecialFolder.Desktop },
{ "MyComputer", Environment.SpecialFolder.MyComputer },
{ "MyDocuments", Environment.SpecialFolder.MyDocuments }, // 旧称 Personal と同義
{ "UserProfile", Environment.SpecialFolder.UserProfile }
};
public MainForm()
{
Text = "FolderBrowserDialog: RootFolder 実践";
Width = 720;
Height = 200;
StartPosition = FormStartPosition.CenterScreen;
var lblRoot = new Label { Text = "RootFolder:", Left = 12, Top = 16, AutoSize = true };
rootCombo = new ComboBox
{
Left = 100,
Top = 12,
Width = 180,
DropDownStyle = ComboBoxStyle.DropDownList
};
rootCombo.Items.AddRange(new object[] { "Desktop", "MyComputer", "MyDocuments", "UserProfile" });
rootCombo.SelectedIndex = 0;
rootCombo.SelectedIndexChanged += (s, e) => SetInitialPathForCurrentRoot();
var lblInit = new Label { Text = "初期パス(SelectedPath):", Left = 300, Top = 16, AutoSize = true };
initialPathText = new TextBox
{
Left = 440,
Top = 12,
Width = 250,
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
};
var lblResult = new Label { Text = "結果:", Left = 12, Top = 60, AutoSize = true };
resultText = new TextBox
{
Left = 60,
Top = 56,
Width = 630,
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right,
ReadOnly = true
};
browseButton = new Button { Text = "参照...", Left = 12, Top = 100, Width = 90 };
browseButton.Click += BrowseButton_Click;
Controls.AddRange(new Control[] { lblRoot, rootCombo, lblInit, initialPathText, lblResult, resultText, browseButton });
// 既定 Root に合わせて初期パスを設定
SetInitialPathForCurrentRoot();
}
private void SetInitialPathForCurrentRoot()
{
var key = (string)rootCombo.SelectedItem;
switch (key)
{
case "Desktop":
initialPathText.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
break;
case "MyComputer":
// MyComputer 自体は実パスではないため、ドライブなど配下の妥当なパスを指定する
initialPathText.Text = @"C:\";
break;
case "MyDocuments":
initialPathText.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
break;
case "UserProfile":
initialPathText.Text = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
break;
default:
initialPathText.Text = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
break;
}
}
private void BrowseButton_Click(object sender, EventArgs e)
{
using (var dialog = new FolderBrowserDialog())
{
var key = (string)rootCombo.SelectedItem;
dialog.RootFolder = rootMap[key];
dialog.Description = $"RootFolder = {key} でフォルダを選択してください";
dialog.ShowNewFolderButton = true;
var init = initialPathText.Text;
if (!string.IsNullOrWhiteSpace(init))
{
dialog.SelectedPath = init; // RootFolder 配下であることが望ましい
}
var result = dialog.ShowDialog(this); // 親を指定
if (result == DialogResult.OK)
{
resultText.Text = dialog.SelectedPath;
}
}
}
}
コード解説(ポイント別)
(1)Root の切り替え:rootMap で UI 表示名と Environment.SpecialFolder を対応付け、dialog.RootFolder にそのまま渡しています。
(2)SelectedPath の整合性:MyComputer は実パスではないため、初期選択を C:\ などの「配下」にある実在パスへ寄せています。これにより初期展開が確実になり、ユーザーの操作がスムーズです。
(3)説明文と新規フォルダ:Description でガイダンスを表示し、ShowNewFolderButton で新規フォルダ作成も許可。業務ツールでは「保存先をこの範囲に限定したい」要件と相性が良いです。
(4)親ウィンドウの指定:ShowDialog(this) としてオーナーを明示し、背面に隠れる問題を避けています。
つまづきポイント
・SelectedPath が Root 外:RootFolder の外側を SelectedPath に入れると初期展開が無視・フォールバックされることがあります。MyComputer なら C:\ 等を指定。
・特殊フォルダの見え方:Environment.SpecialFolder の一部は OS のエクスプローラ設定や権限で表示が変わる場合があります。テスト端末で実際の見え方を確認しましょう。
・権限と存在確認:アクセス権のない場所や存在しないドライブ(例:D:\ 不在)を初期値にすると展開に失敗します。存在チェックや例外対策を。
・旧来 UI の制約:ダイアログは古いスタイルのため、ドラッグ&ドロップや高度なフィルタリングは非対応。必要ならカスタム UI も検討します。
・別名の混乱:MyDocuments は旧称 Personal と同義です。サンプルや記事によって表記が違う点に注意。
まとめ
RootFolder は「どこからどこまで辿れるか」を決める根本設定です。SelectedPath をその配下に置く、MyComputer を選ぶ場合は実在ドライブを初期値にする、という2点を守れば、ユーザーは迷わず目的の保存先・参照先を選べます。要件上の保存範囲を限定したいときにも有効です。



コメント