[C#][Windows Formsアプリ][FolderBrowserDialog] RootFolder を使って探索範囲を制御する

スポンサーリンク

はじめに

本記事では、Windows Forms の FolderBrowserDialog における RootFolder プロパティを解説します。RootFolder はダイアログの「ツリーの最上位(どこから辿れるか)」を制御します。SelectedPath(初期選択)や戻り値との関係、よく使う設定例、実務でハマりがちな注意点を、初心者にもわかりやすく整理します。

説明

RootFolderEnvironment.SpecialFolder 列挙体で指定し、フォルダ選択ダイアログの「探索可能な範囲の起点」を決めます。既定値は Desktop で、ユーザーはデスクトップ配下(ドライブやユーザーフォルダなどへ)を辿れます。

代表的な値とイメージは以下の通りです。

Desktop:通常のエクスプローラと同様の起点。最も汎用的。
MyComputer:PC(このPC)配下が起点。最上位にドライブ(C:\ など)が並ぶ。
MyDocuments:ドキュメントフォルダをルートに限定。ユーザーデータの保存先を固定したいときに便利。
UserProfile:ユーザープロファイル(例:C:\Users\ユーザー名)配下に限定。

重要:SelectedPath との関係
表示前に SelectedPath を設定すると、ダイアログの初期展開位置になります。ただし、そのパスは RootFolder の配下である必要があります。配下でない場合、初期展開は無視されたり、RootFolder 直下にフォールバックすることがあります。例えば RootFolder = MyComputer のときは、SelectedPathC:\(または存在するドライブ)などにしておくのが安全です。

サンプルコード

以下は 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点を守れば、ユーザーは迷わず目的の保存先・参照先を選べます。要件上の保存範囲を限定したいときにも有効です。

Please follow and like us:

コメント

タイトルとURLをコピーしました