宇宙仮面の
C# Programming

 
Image

フォルダーを選択するダイアログ(FolderBrowserFolder)


開発環境: Visual Studio 2002
.NET Framework V1.0 では、フォルダを選択するダイアログが`標準でサポートされておらず、自分で作るとか、未サポートのメソッドを使うとか、VBコンパチライブラリを使う必要がありました。

.Net Framework V1.1 以降では、FolderBrowserDialog が標準でサポートされるようになり、楽になっています。

以下の記事は、V1.0の名残です。

System.Windows.Forms.Design.FolderNameEditor
System.Windows.Forms.Design.FolderNameEditor.FolderBrowserFolder

次のような機能のForm アプリケーションを作る。
  • ディレクトリを選択するダイアログ。
注意: 

このFolderNameEditorのヘルプを見てもらえばわかると思いますが、"FolderNameEditor 型は、.NET Framework インフラストラクチャのサポートを目的としています。独自に作成したコード内で直接使用することはできません。" となっており、マイクロソフトのサポート対象外です。

趣味で書いているぶんにはいいけど、業務で使用する場合には使うべきではありません。

せっかく、.NET になったのだけど、この機能はいまだに SHBrowseForFolder シェルファンクションを使うしかないようです。

C# メイリングリストの [CS:01403] Re: FolderNameEditor で自動展開
またはhttp://www.codeproject.com/cs/miscctrl/FolderBrowser.asp
を参照してください。
参考となる URL は、
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=199&lngWId=10

誰が最初に見つけたのか知りませんが、よく見つけますね!
とりあえず、作って確かめてみないと気がすまないたちなので、作ってみました。

Image

FolderNameEditor, FolderBrowserFolder では、つぎのようなプロパティが使えます。
プロパティType
Public DirectoryPath string Getのみ。
Public Descriptionstring
Protected StartLocationSystem.Windows.Forms.Design.FolderNameEditor.FolderBrowserFolder
Protected StyleRestrictToFilesystem System.Windows.Forms.Design.FolderNameEditor.FolderBrowserStyles

しかし、StartLocation , Styles は、HELPでは、”この型は、.NET Framework インフラストラクチャのサポートを目的としています。独自に作成したコード内で直接使用することはできません。”とあり、protected になっています。このため、継承したダイアログの public メソッドの引数にすることができません。
引数で変更できるようにすると一段処理を入れないといけないので、みにくくなるのでやめました。
DirectoryPicker をテストするため Windows.Form も一緒に作りました。
この中で、DirectoryPicker のインスタンスのShowDialog() をたたいています。
ディレクトリパスの取得結果は、次のようにPath のテキストボックスに表示しています。
Image
作り方

1. 新しいWindows アプリケーションソリューションを作ります。
2. ソリューションエクスプローラから、右クリックで ”追加”→”クラスの追加”で、次のように新しいクラス(DirPicker.cs 任意のファイル名)を作ります。
Image

3. 次に DirPicker.cs の中身を書きます。

注意:
このままコンパイルすると
”型または名前空間名 'FolderNameEditor' が見つかりませんでした。ディレクティブを使うかアセンブリ参照を使ってください。” というエラーになります。
そこで、ソリューションエクスプローラから、右クリックで ”参照の追加”で、FolderNameEditorへの参照が可能になるようにします。

4. ソリューションエクスプローラから、右クリックで ”参照の追加” を押すと、次のような”参照の追加”ダイアログが表示されます。

Image

5. FolderNameEditor をHELPで見てもらえばわかるように、
名前空間System.Windows.Forms.Design
アセンブリ System.Design (System.Design.dll 内)
となっているのがわかります。そこで、.NET タブから、"System.Design.dll" を選択し、”選択”ボタンを押します。
この状態が、上のダイアログです。

6. 最後に、OKを押せばコンパイルが通るようになるはずです。

7. あとは、次のように呼び出せばOK。テストダイアログの説明はいらないでしょう。
        Uchukamen.IO.DirectoryPicker dirPicker = new Uchukamen.IO.DirectoryPicker();
        string dir = dirPicker.ShowDialog();
以下ソースコード。
ファイル名説明
DirPicker.csFolderNameEditorの継承クラス
Form1.csDirectoryPicker をテストするための Windows.Form

変更履歴: 2003/6/26 ShowDialog で DialogResult を返すように変更。


DirPicker.cs

using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace Uchukamen.IO
{
    /// <summary>
    /// DirectoryPicker の概要の説明です。
    /// System.Windows.Forms.Design.FolderNameEditorを継承します。
    /// </summary>
    public class DirectoryPicker:FolderNameEditor
    {
        private FolderNameEditor.FolderBrowser fBrowser;

        /// <summary>
        /// FolderNameEditor.FolderBrowserインスタンスを生成します。
        /// 
        /// StartLocation は、Desktop, Favorites, MyComputer, MyDocuments,
        ///   MyPictures, NetAndDialUpConnections, NetworkNeighborhood,
        ///   Printers, Recent, SendTo, StartMenu, Templates より選択する。
        ///   
        /// Styles は、BrowseForComputer, BrowseForEverything, BrowseForPrinter,
        ///   RestrictToDomain, RestrictToFilesystem, RestrictToSubfolders,
        ///   ShowTextBox  より選択する。
        /// </summary>
        public DirectoryPicker()
        { 
            fBrowser = new FolderNameEditor.FolderBrowser(); 
            fBrowser.StartLocation = FolderNameEditor.FolderBrowserFolder.Desktop;
            fBrowser.Style = FolderNameEditor.FolderBrowserStyles.ShowTextBox;
        }
        
        ~DirectoryPicker()
        {
            fBrowser.Dispose(); 
        }

        /// <summary>
        /// ShowDialog() でモーダルダイアログを表示します。
        /// </summary>
        /// <returns>string selectedDirectoryPath</returns>
        /// 
        
        public DialogResult ShowDialog()
        {
            return fBrowser.ShowDialog(); 
        }

        public string Description
        {
            get 
            {
                return fBrowser.Description; 
            }
            set 
            {
                fBrowser.Description = value; 
            }
        }

        public string DirectoryPath
        {
            get 
            {
                return fBrowser.DirectoryPath; 
            }
        }
    }
}

Form1.cs

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace TestDirPicker2
{
    /// <summary>
    /// Form1 の概要の説明です。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.TextBox textBoxDescription;
        private System.Windows.Forms.TextBox textBoxPath;
        private System.Windows.Forms.CheckBox checkBoxForDescription;
        private System.Windows.Forms.GroupBox groupBox1;
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            //
            // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
            //
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.textBoxDescription = new System.Windows.Forms.TextBox();
            this.textBoxPath = new System.Windows.Forms.TextBox();
            this.label3 = new System.Windows.Forms.Label();
            this.checkBoxForDescription = new System.Windows.Forms.CheckBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(328, 128);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(80, 24);
            this.button1.TabIndex = 5;
            this.button1.Text = "Test";
            this.button1.Click += new System.EventHandler(this.OnClick);
            // 
            // textBoxDescription
            // 
            this.textBoxDescription.Enabled = false;
            this.textBoxDescription.Location = new System.Drawing.Point(80, 24);
            this.textBoxDescription.Name = "textBoxDescription";
            this.textBoxDescription.Size = new System.Drawing.Size(312, 19);
            this.textBoxDescription.TabIndex = 1;
            this.textBoxDescription.Text = "";
            // 
            // textBoxPath
            // 
            this.textBoxPath.Location = new System.Drawing.Point(80, 96);
            this.textBoxPath.Name = "textBoxPath";
            this.textBoxPath.ReadOnly = true;
            this.textBoxPath.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal;
            this.textBoxPath.Size = new System.Drawing.Size(328, 19);
            this.textBoxPath.TabIndex = 4;
            this.textBoxPath.Text = "";
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(24, 96);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(40, 16);
            this.label3.TabIndex = 3;
            this.label3.Text = "Path";
            // 
            // checkBoxForDescription
            // 
            this.checkBoxForDescription.Location = new System.Drawing.Point(16, 24);
            this.checkBoxForDescription.Name = "checkBoxForDescription";
            this.checkBoxForDescription.Size = new System.Drawing.Size(56, 24);
            this.checkBoxForDescription.TabIndex = 0;
            this.checkBoxForDescription.Text = "Set";
            this.checkBoxForDescription.CheckedChanged += new System.EventHandler(this.OnCheckedChanged);
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.textBoxDescription);
            this.groupBox1.Controls.Add(this.checkBoxForDescription);
            this.groupBox1.Location = new System.Drawing.Point(16, 16);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(400, 64);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Description";
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(424, 166);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.textBoxPath);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.groupBox1);
            this.Name = "Form1";
            this.Text = "Test Directory Picker";
            this.groupBox1.ResumeLayout(false);
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void OnClick(object sender, System.EventArgs e)
        {
            Uchukamen.IO.DirectoryPicker dirPicker = new Uchukamen.IO.DirectoryPicker();
            if (this.checkBoxForDescription.Checked)
                dirPicker.Description = this.textBoxDescription.Text;
            DialogResult result = dirPicker.ShowDialog();
            if(result == DialogResult.OK)
                this.textBoxPath.Text = dirPicker.DirectoryPath;
            else
                this.textBoxPath.Text = "The operation has been canceled!";
        }

        private void OnCheckedChanged(object sender, System.EventArgs e)
        {
            this.textBoxDescription.Enabled = this.checkBoxForDescription.Checked;
        }
    }
}