フォルダーを選択するようにOpenFileDialogを構成するにはどうすればよいですか?


251

VS .NETでは、プロジェクトのフォルダーを選択すると、OpenFileDialogまたはSaveFileDialogのようなダイアログが表示されますが、フォルダーのみを受け入れるように設定されています。私はこれを見て以来、それがどのように行われるのか知りたいと思っていました。FolderBrowserDialogは知っていますが、そのダイアログがあまり好きではありません。最初は小さすぎて、パスを入力できることを利用できません。

これで.NETからこれを行う方法がないことはほぼ確実ですが、アンマネージコードからそれを行う方法にも興味があります。ダイアログを最初から完全に再実装する前に、どのようにダイアログを変更してこの動作をさせることができますか?

私は、FolderBrowserDialogを認識していることを再言したいのですが、この方法でダイアログを構成する方法に本当に興味があることに加えて、それを使用したくない場合もあります。FolderBrowserDialogだけを使用するように指示すると、一貫したUIエクスペリエンスを維持するのに役立ちますが、好奇心を満たすことができないため、回答としてカウントされません。

Vista固有のものでもありません。このダイアログはVS .NET 2003以降に表示されているため、Win2kとWinXPで実行できます。これは、「これを行うための適切な方法を知りたい」という質問ではなく、「VS 2003で最初にそれをやりたかったので、これについて知りたい」という質問のほうが多いです。Vistaのファイルダイアログにはこれを実行するオプションがあることを理解していますが、それはXPで機能しており、動作させるために何かをしたことはわかっています。Vistaは質問のコンテキストに存在しないため、Vista固有の回答は回答ではありません。

更新:実用的なサンプルが付属しているため、Scott Wisniewskiの回答を受け入れますが、Sergeはダイアログのカスタマイズ(確かに.NETからは厄介ですが、機能します)を指摘し、そのMSを理解するためのMark Ransomを評価する価値があると思いますこのタスクのカスタムダイアログをロールした可能性があります。


7
codeprojectcodeproject.com/Articles/44914/…からの単純な解決策 [OpenFileDialogでファイルとフォルダの両方を選択するための鍵は、ValidateNamesプロパティとCheckFileExistsプロパティをfalseに設定することです(dialog.ValidateNames = false; dialog.CheckFileExists = false)そして、FileNameを特別なキーワードに設定して、フォルダーが確実に選択されるようにします(dialog.FileName = "Folder Selection";)。]
Riju

3
これを回答として送信してください。私のプロジェクトでうまくいきました。
CigarDoug、2015

@Rijuは後続期間dialog.FileName = "Folder Selection"dialog.FileName = "Folder Selection."一緒になっているはずですか?とにかく、私はそれをどちらかの方法で「開く」の2回目のクリックでPowershellで動作させることができません。CheckFileExistsがfalseであるにもかかわらず、ファイルが見つからないというメッセージが表示され続ける
ComradeJoecool

nvm、dialog.CheckFileExists = 0falseではなくpowershell設定で問題が解決しました
ComradeJoecool

回答:


57

私が書いたダイアログはOpenFileOrFolderダイアログと呼ばれ、フォルダーまたはファイルを開くことができます。

AcceptFiles値をfalseに設定すると、フォルダー受け入れモードでのみ動作します。

ここからGitHubからソースをダウンロードできます


4
非常に興味深く、間違いなく私が考えていたほど複雑です。注釈を付けて、それが何をするかを指摘する可能性はありますか?これは他のコメントとともに、MSがおそらく独自のダイアログをロールバックしただけだと私に思わせます。
OwenP、2009

1
ソリューションをビルドしようとすると、次のエラーが表示されます...残念ながら、私の強みではないc ++ ...エラー1は、インクルードファイル 'afxres.h'を開くことができません。
イグナシオソレルガルシア

1
@SoMoS、および同じ問題のある他のユーザー:ファイルWindowsFormsApplication1.csprojで100行を編集して、設定に一致させます。私の場合、「9.0」を「10.0」(2回)に変更し、「(x86)」(2回)を削除する必要がありました。
RenniePet

2
コード(zip)をダウンロードして.h(C)ファイルを見つけ、インクルードファイル 'sal.h'を開けないなどのエラーでコンパイルしました。
Lei Yang

2
このソリューションは、VS2010およびVS2017でも機能しません。
AleX_ 2017

49

FolderBrowserDialogEx-組み込みのFolderBrowserDialogの再利用可能な派生物を使用できます。これにより、UNCパスも含めてパスを入力できます。それを使用してコンピューターまたはプリンターを参照することもできます。組み込みのFBDと同じように機能しますが、...優れています。

(編集:このダイアログはファイルまたはフォルダーを選択するように設定できることを指摘しておく必要があります。)

完全なソースコード(1つの短いC#モジュール)。自由。MS-Publicライセンス。

それを使用するコード:

var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
dlg1.Description = "Select a folder to extract to:";
dlg1.ShowNewFolderButton = true;
dlg1.ShowEditBox = true;
//dlg1.NewStyle = false;
dlg1.SelectedPath = txtExtractDirectory.Text;
dlg1.ShowFullPathInEditBox = true;
dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;

// Show the FolderBrowserDialog.
DialogResult result = dlg1.ShowDialog();
if (result == DialogResult.OK)
{
    txtExtractDirectory.Text = dlg1.SelectedPath;
}

7
私が気分を害した場合は申し訳ありませんが、質問をして「私はこれ以外のことではなく、この特定のものが欲しい」と綴り、人々に要求されていないことを陽気に提案してもらうのはイライラします。フォルダーブラウザーダイアログではなく、ファイルブラウザーダイアログが必要でした。
OwenP 2009年

15
質問の言い方では、フォルダーピッカーダイアログを要求しているように聞こえますが、そうではありませんか?とにかく、これはまさに私が探していたものです+1
Tim

間違いなくこれまでのところ最良の答え
Vasil Popov

1
それでも、答えはリンクのみの答えであるという事実は変わりません。オフサイトのリソースでホストされているコードの使用方法を示すことは、そのリンクも一時的または永続的に利用できなくなったときに役に立たなくなります。ルールは理由があるので、この貢献はそれらのルールと矛盾しています。
IInspectable 2018年

1
私はこの回答を見ましが、明らかにそれはオフサイトのリソースを参照していません。したがって、「その他すべての答え」は明らかに間違っています。私が過剰に反応しているように感じた場合は、おそらくメタで問題を提起してルールについて話し合う必要があります。私はしません。私はそれらを適用します。
IInspectable 2018年

48

Windows APIコードパックがあります。CommonOpenFileDialogクラスを含むシェル関連のものがたくさんあります(Microsoft.WindowsAPICodePack.Dialogs名前空間内)ます。これは完璧なソリューションです-フォルダーのみが表示された通常のオープンダイアログ。

これを使用する方法の例を次に示します。

CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();

残念ながら、Microsoftはこのパッケージを出荷しなくなりましたが、何人かの人々が非公式にバイナリをNuGetにアップロードしています。一例がここにあります。このパッケージは、シェル固有のものです。必要な場合は、同じユーザーが、元のパッケージに存在するより多くの機能を提供する他のいくつかのパッケージを持っています。


1
これがWindows APIコードパックに含まれていることは知りませんでした。これを指摘していただきありがとうございます。
Patrick Klug、2011

10
CommonOpenFileDialogクラスはWindows Vista以降にのみ存在するため、古いオペレーティングシステムでは例外をスローします
Rachel

1
Windows APIコードパックの参照方法を教えてください。
jeff 2013年

1
アーカイブギャラリーは廃止されました。、または...]リンクが言うようでした、これはそれのための新しい場所で?
デフォルトの

3
ちなみに、CommonOpenFileDialogクラスはMicrosoft.WindowsAPICodePack.Dialogs名前空間にあります(しばらくしてから検索しました)。
morgb 2016

35

Ookii.Dialogsのパッケージには、ブラウザのダイアログフォルダの新しい(Vistaのスタイル)の周りのマネージラッパーが含まれています。また、古いオペレーティングシステムでは正常に低下します。


2
BSDスタイルでライセンスされたオープンソースです。
Roman Starkov、2010

7
唯一の問題は、.netフレームワークのクライアントプロファイルをターゲットとして使用させないことです。
Kugel

2
とても良い解決策です。これは私の見解です。3年以来、まさに私が探していたもの。
Samuel、

1
このソリューションの別の問題:存在しないパスを貼り付けることができません。比較的マイナーなものですが、それでも残念です。
Roman Starkov

1
- スタイルのフォルダダイアログが必要な場合に最適回答ですOpenFileDialog
アクア2013年

27

そのためにはFolderBrowserDialogを使用する方が良いでしょう。

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

9
私はあることを認識していますより良い FolderBrowserDialogを使用します。どうやってそれが行われたのか知りたいです。FolderBrowserDialogはとにかく多くの点で悪臭を放ちます。Vistaでも、場所バーはありません。おもしろいのですが、これまで3つのVSバージョンでMSが回避していたのはおかしいです。
OwenP、2009

24
FolderBrowserDialogには、多くのユーザビリティの問題があります。実際にアプリケーションに組み込むことは考えていません。使いやすさが大幅に向上したダイアログについては、私の投稿を参照してください
Scott Wisniewski、

6
FolderBrowserDialogでは、次のことはできません
。-

89
FolderBrowserDialogは本当に恐ろしいUIです。
マッケニール2010

32
真剣に、人々は、この煩わしいダイアログをあなたのアプリケーションに置くことをやめてください。以前のコメントで強調表示されているように、非常に悪いUIがあります。
Roman Starkov

23

検索の時間の後、私が見つかりました。この答えをすることによってleetNightShade作業溶液

このソリューションが他のソリューションよりもはるかに優れていると私が信じている3つの点があります。

  1. 使い方は簡単です。 プロジェクトに2つのファイル(とにかく1つに組み合わせることができます)を含める必要があります。
  2. 標準のFolderBrowserDialogにフォールバックしますXP以前のシステムで使用ます。
  3. 作成者は、ユーザーが適切と考える目的でコードを使用する許可を与えます。

    あなたが自由に取得してコードを自由に操作できるようなライセンスはありません。

ここからコードをダウンロードしてください


@MattDavis:.NET Framework 4.0(StandardとClient Profileの両方)で動作することを確認しました。プロジェクトにFolderSelectDialog.csとReflector.csの両方が追加されていることを確認してください。ただし、Windows 8で実行していますか?Win7コンピューターでテストしました。
Alex Essilfie 2013年

@Alex Essilfie、あなたは正しいです。それを自分のプロジェクトに取り込む際に何か間違ったことをしたに違いありません。明確にするために、以前のコメントを削除します。
Matt Davis

複数のオプションを実行し、これが最良であると考えました。推奨。
Jaded

私のためにwindows 10で働いた。良い簡単な解決策
デビッドウィルトン

古いシステムのフェイルオーバーを尊重する必要がある
Mike M

17

正確な音声コピー、Windows XPでこのように機能します。標準のファイルを開くダイアログが表示されますが、ファイル名フィールドには「ファイル名は無視されます」というテキストが含まれています。

ここで推測するだけですが、ダイアログに大幅な変更が加えられるたびに、文字列がコンボボックスエディットコントロールに挿入されると思います。フィールドが空白ではなく、ダイアログフラグがファイルの存在をチェックしないように設定されている限り、ダイアログは正常に閉じることができます。

編集:これは思ったよりずっと簡単です。これがC ++ / MFCのコードです。選択した環境に変換できます。

CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this);
dlg.DoModal();

編集2:これはC#への翻訳であるはずですが、私はC#に堪能ではないので、機能しない場合は撮影しないでください。

OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.FileName = "Filename will be ignored";
openFileDialog1.CheckPathExists = true;
openFileDialog1.ShowReadOnly = false;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
    // openFileDialog1.FileName should contain the folder and a dummy filename
}

編集3:最後に、問題の実際のダイアログをVisual Studio 2005で調べました(以前はアクセスできませんでした)。標準のファイルを開くダイアログではありません!Spy ++でウィンドウを検査し、開いている標準ファイルと比較すると、構造とクラスの名前が一致していないことがわかります。よく見ると、ダイアログの内容の違いを見つけることができます。私の結論は、MicrosoftがVisual Studioの標準ダイアログを完全に置き換えて、この機能を提供したということです。私自身のソリューションまたは類似のものは、自分でコードを最初からコーディングするつもりがない限り、可能な限り近くなります。


17

OK、最初のドットを接続してみましょう;-) Spy ++またはWinspectorで少し再生すると、VSプロジェクトの場所の[フォルダ]テキストボックスが標準ダイアログのカスタマイズであることを示しています。これは、メモ帳などの標準的なファイルダイアログのファイル名テキストボックスと同じフィールドではありません。

そこから、VSはファイル名とファイルタイプのtextboxes / comboboxesを隠し、カスタムダイアログテンプレートを使用して、ダイアログの下部に独自の部分を追加します。

編集:そのようなカスタマイズの例とそれを行う方法を次に示します(Win32では.NETではありません):

m_ofnは、ファイルダイアログの下にあるOPENFILENAME構造体です。次の2行を追加します。

  m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
  m_ofn.Flags |= OFN_ENABLETEMPLATE;

IDD_FILEDIALOG_IMPORTXLIFFは、ダイアログの下部に追加されるカスタムダイアログテンプレートです。以下の赤い部分を参照してください。 (ソース:apptranslator.com代替テキスト

この場合、カスタマイズされたパーツはラベル+ハイパーリンクのみですが、任意のダイアログにすることができます。フォルダのみの選択を検証できる[OK]ボタンを含めることができます。

しかし、ダイアログの標準部分にあるコントロールのいくつかをどのように取り除くのか、私にはわかりません。

このMSDN記事の詳細。


1
それは私が過去に聞いたいくつかの説明のように聞こえますが、私はそのコンセプトのデモンストレーションを見たことがありません。それを行うことに関するMSDNドキュメントのウォークスルーはありますか?
OwenP、2009

10

ファイルダイアログをサブクラス化して、そのすべてのコントロールにアクセスできます。それぞれに、ウィンドウハンドルを取得するために使用できる識別子があります。次に、それらを表示および非表示にしたり、選択の変更などについてメッセージを取得したりできます。これは、どれだけの努力をしたいかによって異なります。

WTLクラスサポートを使用してファイルダイアログをカスタマイズし、カスタムプレースバーとプラグインCOMビューを含めました。

MSDNは、Win32を使用してこれを行う方法に関する情報を提供していますこのCodeProject記事には例が含まれており、このCodeProject記事には.NETの例が含まれています。


10

このようなコードを使用できます

  • フィルターはファイルを非表示にする
  • ファイル名は最初のテキストを隠す

ファイル名のテキストボックスを高度に非表示にするには、OpenFileDialogExを確認する必要があります

コード:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

シンプルで、Windows 7以降に必要なもの
Hao Nguyen

また、フラグにはOFN_NOVALIDATEが必要です
ゴブリンの錬金術師

5

VS2008を使用してVistaを使用していると思いますか?その場合は、VOSファイルダイアログIFileDialogを呼び出すときにFOS_PICKFOLDERSオプションが使用されていると思います。.NETコードでは、動作させるために多くの危険なP / Invoke相互運用コードが必要になると思います。


1
Vista固有。私はこれをWindows XP上のVS 2003で最初に見ました。
OwenP 2009

2

最初の解決策

私はこれをlyquidity.comの Bill Seddonによる.NET Win 7スタイルのフォルダー選択ダイアログのクリーンアップバージョンとして開発しました(所属はありません)。(私はこのページの別の回答から彼のコードを知りました)。彼のソリューションは、この焦点を絞った目的には不要な追加のReflectionクラスを必要とし、例外ベースのフロー制御を使用し、リフレクション呼び出しの結果をキャッシュしないため、自分で独自に作成しました。ネストされた静的クラスは、メソッドが呼び出されない場合に静的リフレクション変数が入力されないようにするためのものです。十分に高いWindowsバージョンでない場合は、Vista以前のダイアログにフォールバックします。Windows 7、8、9、10以降で動作するはずです(理論的には)。VistaDialogShow

using System;
using System.Reflection;
using System.Windows.Forms;

namespace ErikE.Shuriken {
    /// <summary>
    /// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
    /// </summary>
    public class FolderSelectDialog {
        private string _initialDirectory;
        private string _title;
        private string _fileName = "";

        public string InitialDirectory {
            get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
            set { _initialDirectory = value; }
        }
        public string Title {
            get { return _title ?? "Select a folder"; }
            set { _title = value; }
        }
        public string FileName { get { return _fileName; } }

        public bool Show() { return Show(IntPtr.Zero); }

        /// <param name="hWndOwner">Handle of the control or window to be the parent of the file dialog</param>
        /// <returns>true if the user clicks OK</returns>
        public bool Show(IntPtr hWndOwner) {
            var result = Environment.OSVersion.Version.Major >= 6
                ? VistaDialog.Show(hWndOwner, InitialDirectory, Title)
                : ShowXpDialog(hWndOwner, InitialDirectory, Title);
            _fileName = result.FileName;
            return result.Result;
        }

        private struct ShowDialogResult {
            public bool Result { get; set; }
            public string FileName { get; set; }
        }

        private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title) {
            var folderBrowserDialog = new FolderBrowserDialog {
                Description = title,
                SelectedPath = initialDirectory,
                ShowNewFolderButton = false
            };
            var dialogResult = new ShowDialogResult();
            if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
                dialogResult.Result = true;
                dialogResult.FileName = folderBrowserDialog.SelectedPath;
            }
            return dialogResult;
        }

        private static class VistaDialog {
            private const string c_foldersFilter = "Folders|\n";

            private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
            private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
            private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
            private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
            private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
            private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
            private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
            private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialogNative+FOS")
                .GetField("FOS_PICKFOLDERS")
                .GetValue(null);
            private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
                .GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
                .GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
            private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
            private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
            private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");

            public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title) {
                var openFileDialog = new OpenFileDialog {
                    AddExtension = false,
                    CheckFileExists = false,
                    DereferenceLinks = true,
                    Filter = c_foldersFilter,
                    InitialDirectory = initialDirectory,
                    Multiselect = false,
                    Title = title
                };

                var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
                s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
                s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
                var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
                s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);

                try {
                    int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
                    return new ShowDialogResult {
                        Result = retVal == 0,
                        FileName = openFileDialog.FileName
                    };
                }
                finally {
                    s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
                }
            }
        }

        // Wrap an IWin32Window around an IntPtr
        private class WindowWrapper : IWin32Window {
            private readonly IntPtr _handle;
            public WindowWrapper(IntPtr handle) { _handle = handle; }
            public IntPtr Handle { get { return _handle; } }
        }
    }
}

Windowsフォームでは次のように使用されます。

var dialog = new FolderSelectDialog {
    InitialDirectory = musicFolderTextBox.Text,
    Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
    musicFolderTextBox.Text = dialog.FileName;
}

もちろん、そのオプションとそれが公開するプロパティをいじることができます。たとえば、Vistaスタイルのダイアログで複数選択が可能です。

2番目のソリューション

Simon Mourierは、 Windows APIに対して相互運用機能を直接使用してまったく同じジョブを実行する方法を示す回答提供しましたが、古いバージョンのWindowsの場合、古いスタイルのダイアログを使用するには彼のバージョンを補足する必要があります。残念ながら、解決策を練ったとき、私はまだ彼の投稿を見つけていませんでした。毒に名前を付けてください!


空のハンドルを使用してこの細かいダイアログをダイアログボックスとして(たとえば、コンソールタイプのアプリから)呼び出す例:var dialog = new FolderSelectDialog {InitialDirectory = "C:\\"、Title = "Select a音楽をインポートするフォルダー "}; if(dialog.Show()){string myFolder = dialog.FileName; }
Philm

注:コメントとして私の使用例は、そのため、読み取ることが困難である:「例」オリジナルの使用に最も重要な変更点:使用InitialDirectoryとタイトルの間にカンマ...
Philm

1

Codeprojectからこれを試してください(へのクレジット):

それはあなたが話しているのと同じダイアログだと思います-スクリーンショットを追加すると役立つかもしれませんか?

bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
    bool retVal = false;

    // The BROWSEINFO struct tells the shell how it should display the dialog.
    BROWSEINFO bi;
    memset(&bi, 0, sizeof(bi));

    bi.ulFlags   = BIF_USENEWUI;
    bi.hwndOwner = hOwner;
    bi.lpszTitle = szCaption;

    // must call this if using BIF_USENEWUI
    ::OleInitialize(NULL);

    // Show the dialog and get the itemIDList for the selected folder.
    LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

    if(pIDL != NULL)
    {
        // Create a buffer to store the path, then get the path.
        char buffer[_MAX_PATH] = {'\0'};
        if(::SHGetPathFromIDList(pIDL, buffer) != 0)
        {
            // Set the string value.
            folderpath = buffer;
            retVal = true;
        }       

        // free the item id list
        CoTaskMemFree(pIDL);
    }

    ::OleUninitialize();

    return retVal;
}

images.google.com/…不明な場合は調査してください。私が欲しかったことを説明しましたが、FolderBrowserDialogはすでに回答として失格になっています。
OwenP 2009

「FolderBrowserDialogは知っていますが、そのダイアログはあまり好きではありません。最初は小さすぎて、パスを入力できるという利点がありません。」自分で調査してください。そこにパスを入力できます。とにかく、少しあいまいな質問だと思いますので、頑張ってください。
demoncodemonkey、2009

@demoncodemonkey:パスの一部を入力してから、目的のターゲットに移動することはできません。FileOpenDialogが提供するオプションほど便利ではありません。
Treb

1

Vistaでは、あなたは使用することができますIFileDialogを FOS_PICKFOLDERSオプションセットで。これにより、フォルダーを選択できるOpenFileDialogのようなウィンドウが表示されます。

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

古いWindowsの場合は、いつでもフォルダー内のファイルを選択してトリックすることができます。

.NET Framework 2.0以降で動作する実際の例は、こちらにあります


1

このようなコードを使用できます

フィルターは空の文字列です。ファイル名はAnyNameですが空白ではありません

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

6
私はこれが古い投稿であることを知っていますが、これを試してみたい人のために、開きたいディレクトリに子ディレクトリがまったくない場合を除いて、実際には機能しません。したがって、ユーザーがフォルダを参照して選択し、フォルダパスをテキストボックスに入力する場合、「開く」を選択すると、ディレクトリC:\ SomeParentDir \ SomeChildDirが存在する場合、ユーザーはC:\ SomeParentDirを選択できません。 "子ディレクトリに移動します。
ジム

すばらしい試みですが、テキストボックス内の "AnyFile"がユーザーがテキストを上書きするのを待っているだけなので、これはひどいUIになります。しかし、いい試練..
GY


-1

私は質問が構成に関するものであることを知っていますOpenFileDialogが、Googleが私をここに連れてきたのを見て、フォルダーのみを探している場合は、FolderBrowserDialog代わりに以下の別のSO質問で答える代わりに

vb.netでファイルを開くダイアログを使用してパスを指定する方法


誤解を招く。1)それが唯一の選択肢ではありません。2)ほとんどの場合、これは良い選択ではありません。それでも、必要なコードが最小限で済み、より多くのエンドユーザーの時間を費やすことになります。
ニャー猫2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.