質問

ユーザーがディレクトリを選択できるようにするコントロールをユーザーに提示するにはどうすればよいですか?

これを行うネイティブの .net コントロールはないようです。

役に立ちましたか?

解決

FolderBrowserDialog クラス が最良の選択肢です。

他のヒント

string folderPath = "";
FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
    folderPath = folderBrowserDialog1.SelectedPath ;
}

注記:このコードが .Net Framework の将来のバージョンで動作するという保証はありません。ここでリフレクションを通じて行われているように、プライベート .Net フレームワークの内部を使用することは、おそらく全体的には良くありません。Windows API は変更される可能性が低いため、下部に記載されている相互運用ソリューションを使用してください。

Windows 7 のダイアログに似たフォルダー ピッカーをお探しの場合は、下部のテキスト ボックスと左側のナビゲーション ウィンドウからお気に入りや共通の場所をコピーして貼り付ける機能を備えたフォルダー ピッカーにアクセスできます。非常に軽量な方法で。

FolderBrowserDialog UI は非常に最小限です。

enter image description here

ただし、代わりに次のようにすることもできます。

enter image description here

これは、.Net private を使用して Vista スタイルのフォルダー ピッカーを開くクラスです。 IFileDialog コード内で相互運用機能を直接使用せずに、インターフェイスを作成します (.Net がそれを処理します)。Windows のバージョンが十分に高くない場合は、Vista 以前のダイアログに戻ります。(理論上は) Windows 7、8、9、10 以降で動作するはずです。

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

namespace MyCoolCompany.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; } }
        }
    }
}

これをクリーンアップしたバージョンとして開発しました。 .NET Win 7 スタイルのフォルダー選択ダイアログ ビル・セドン著 流動性.com (私には何の所属もありません)。彼のソリューションでは、この焦点を絞った目的には必要のない追加の Reflection クラスが必要で、例外ベースのフロー制御を使用し、リフレクション呼び出しの結果をキャッシュしないため、私が独自のソリューションを作成しました。ネストされた静的 VistaDialog クラスは、次の場合にその静的リフレクション変数が設定されないようになっています。 Show メソッドは決して呼び出されません。

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 スタイルのダイアログで複数選択が可能になります。

また、ご了承ください サイモン・ムーリエが答えました これは、Windows API に対して相互運用機能を使用してまったく同じジョブを直接実行する方法を示しています。ただし、古いバージョンの Windows では、古いスタイルのダイアログを使用するには、このバージョンを補足する必要があります。残念ながら、解決策を考えたとき、私はまだ彼の投稿を見つけていませんでした。あなたの毒に名前を付けてください!

を使用することもできます FolderBrowserDialog からのクラス System.Windows.Forms 名前空間。

TreeView/DirectoryInfo クラスを使用して独自のクラスを作成しようとしないでください。まず、SHBrowseForFolder を使用すると、多くの優れた機能 (アイコン/右クリック/ネットワーク) を無料で利用できます。もう 1 つは、あなたが気づいていない可能性が高い特殊なケース/落とし穴があります。

TreeView を DirectoryInfo クラスと組み合わせて使用​​できます。

フィルタリング、チェックボックスなど、FolderBrowser ダイアログよりもさらに多くの機能については、次のようなサードパーティ コントロールを参照してください。 シェルメガパック。これらはコントロールであるため、モーダル ダイアログとして表示されるのではなく、独自のフォームに配置できます。

または、さらに良いことに、このコードをクラス ファイルに置くこともできます。

using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows.Forms;

internal class OpenFolderDialog : IDisposable {

    /// <summary>
    /// Gets/sets folder in which dialog will be open.
    /// </summary>
    public string InitialFolder { get; set; }

    /// <summary>
    /// Gets/sets directory in which dialog will be open if there is no recent directory available.
    /// </summary>
    public string DefaultFolder { get; set; }

    /// <summary>
    /// Gets selected folder.
    /// </summary>
    public string Folder { get; private set; }


    internal DialogResult ShowDialog(IWin32Window owner) {
        if (Environment.OSVersion.Version.Major >= 6) {
            return ShowVistaDialog(owner);
        } else {
            return ShowLegacyDialog(owner);
        }
    }

    private DialogResult ShowVistaDialog(IWin32Window owner) {
        var frm = (NativeMethods.IFileDialog)(new NativeMethods.FileOpenDialogRCW());
        uint options;
        frm.GetOptions(out options);
        options |= NativeMethods.FOS_PICKFOLDERS | NativeMethods.FOS_FORCEFILESYSTEM | NativeMethods.FOS_NOVALIDATE | NativeMethods.FOS_NOTESTFILECREATE | NativeMethods.FOS_DONTADDTORECENT;
        frm.SetOptions(options);
        if (this.InitialFolder != null) {
            NativeMethods.IShellItem directoryShellItem;
            var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
            if (NativeMethods.SHCreateItemFromParsingName(this.InitialFolder, IntPtr.Zero, ref riid, out directoryShellItem) == NativeMethods.S_OK) {
                frm.SetFolder(directoryShellItem);
            }
        }
        if (this.DefaultFolder != null) {
            NativeMethods.IShellItem directoryShellItem;
            var riid = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"); //IShellItem
            if (NativeMethods.SHCreateItemFromParsingName(this.DefaultFolder, IntPtr.Zero, ref riid, out directoryShellItem) == NativeMethods.S_OK) {
                frm.SetDefaultFolder(directoryShellItem);
            }
        }

        if (frm.Show(owner.Handle) == NativeMethods.S_OK) {
            NativeMethods.IShellItem shellItem;
            if (frm.GetResult(out shellItem) == NativeMethods.S_OK) {
                IntPtr pszString;
                if (shellItem.GetDisplayName(NativeMethods.SIGDN_FILESYSPATH, out pszString) == NativeMethods.S_OK) {
                    if (pszString != IntPtr.Zero) {
                        try {
                            this.Folder = Marshal.PtrToStringAuto(pszString);
                            return DialogResult.OK;
                        } finally {
                            Marshal.FreeCoTaskMem(pszString);
                        }
                    }
                }
            }
        }
        return DialogResult.Cancel;
    }

    private DialogResult ShowLegacyDialog(IWin32Window owner) {
        using (var frm = new SaveFileDialog()) {
            frm.CheckFileExists = false;
            frm.CheckPathExists = true;
            frm.CreatePrompt = false;
            frm.Filter = "|" + Guid.Empty.ToString();
            frm.FileName = "any";
            if (this.InitialFolder != null) { frm.InitialDirectory = this.InitialFolder; }
            frm.OverwritePrompt = false;
            frm.Title = "Select Folder";
            frm.ValidateNames = false;
            if (frm.ShowDialog(owner) == DialogResult.OK) {
                this.Folder = Path.GetDirectoryName(frm.FileName);
                return DialogResult.OK;
            } else {
                return DialogResult.Cancel;
            }
        }
    }


    public void Dispose() { } //just to have possibility of Using statement.

}

internal static class NativeMethods {

    #region Constants

    public const uint FOS_PICKFOLDERS = 0x00000020;
    public const uint FOS_FORCEFILESYSTEM = 0x00000040;
    public const uint FOS_NOVALIDATE = 0x00000100;
    public const uint FOS_NOTESTFILECREATE = 0x00010000;
    public const uint FOS_DONTADDTORECENT = 0x02000000;

    public const uint S_OK = 0x0000;

    public const uint SIGDN_FILESYSPATH = 0x80058000;

    #endregion


    #region COM

    [ComImport, ClassInterface(ClassInterfaceType.None), TypeLibType(TypeLibTypeFlags.FCanCreate), Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")]
    internal class FileOpenDialogRCW { }


    [ComImport(), Guid("42F85136-DB7E-439C-85F1-E4075D135FC8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IFileDialog {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        [PreserveSig()]
        uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow 


        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFileTypeIndex([In] uint iFileType);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetFileTypeIndex(out uint piFileType);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint Unadvise([In] uint dwCookie);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetOptions([In] uint fos);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetOptions(out uint fos);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint Close([MarshalAs(UnmanagedType.Error)] uint hr);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetClientGuid([In] ref Guid guid);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint ClearClientData();

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter);
    }


    [ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IShellItem {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs);

        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder);
    }

    #endregion


    [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    internal static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);

}

そして、このように使用します

using (var frm = new OpenFolderDialog()) {
                if (frm.ShowDialog(this)== DialogResult.OK) {
                    MessageBox.Show(this, frm.Folder);
                }
            }

複数のフォルダーを選択して実行するより良い方法

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

class OpenFolderDialog
{
    //public bool AddExtension { get; set; }
    public bool AutoUpgradeEnabled { get; set; }
    //public bool CheckFileExists { get; set; }
    public bool CheckPathExists { get; set; }
    //public bool DereferenceLinks { get; set; }
    public string Title { get; set; }
    //public string DefaultExt { get; set; }
    public string InitialDirectory { get; set; }
    //public bool ValidateNames { get; set; }
    //public bool SupportMultiDottedExtensions { get; set; }
    //public bool ShowHelp { get; set; }
    public bool Multiselect { get; set; }
    public bool RestoreDirectory { get; set; }
    //public string Filter { get; set; }
    public string SelectedPath { get; private set; }
    public string[] SelectedPaths { get; private set; }

    private FolderBrowserDialog FolderBrowser
    {
        get
        {
            return new FolderBrowserDialog()
            {
                ShowNewFolderButton = true,
                Description = Title,
                SelectedPath = InitialDirectory
            };
        }
    }

    private OpenFileDialog Dialog
    {
        get
        {
            return new OpenFileDialog()
            {
                Title = Title,
                AddExtension = false,
                AutoUpgradeEnabled = AutoUpgradeEnabled,
                CheckFileExists = true,
                CheckPathExists = CheckPathExists,
                DefaultExt = string.Empty,
                DereferenceLinks = false,
                InitialDirectory = InitialDirectory,
                ValidateNames = false,
                SupportMultiDottedExtensions = false,
                ShowHelp = false,
                Multiselect = Multiselect,
                RestoreDirectory = RestoreDirectory,
                Filter = string.Empty,
                FileName = SelectedPath
            };
        }
    }

    /// <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 DialogResult ShowDialog(IntPtr hWndOwner)
    {
        if (Environment.OSVersion.Version.Major >= 6)
        {
            OpenFileDialog dialog = Dialog;
            DialogResult result = VistaDialog.Show(hWndOwner, dialog) != 0 ? DialogResult.Cancel : DialogResult.OK;
            SelectedPath = dialog.FileName;
            SelectedPaths = dialog.FileNames;
            return result;
        }
        else
        {
            FolderBrowserDialog XPDialog = FolderBrowser;
            DialogResult result = XPDialog.ShowDialog();
            SelectedPath = XPDialog.SelectedPath;
            return result;
        }
    }

    private static class VistaDialog
    {
        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 int Show(IntPtr ownerHandle, OpenFileDialog dialog)
        {
            var iFileDialog = s_createVistaDialogMethodInfo.Invoke(dialog, new object[] { });
            s_onBeforeVistaDialogMethodInfo.Invoke(dialog, new[] { iFileDialog });
            s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint)s_getOptionsMethodInfo.Invoke(dialog, new object[] { }) | s_fosPickFoldersBitFlag });
            var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { dialog }), 0U };
            s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);

            try
            {
                return (int)s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });

            }
            finally
            {
                s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
            }
        }
    }
}

使用法:

OpenFolderDialog folder = new OpenFolderDialog()
            {
                Title = "Select destination folder",
                AutoUpgradeEnabled = true,
                CheckPathExists = true,
                InitialDirectory =
                Environment.GetFolderPath
                (Environment.SpecialFolder.DesktopDirectory),
                Multiselect = true,
                RestoreDirectory = true
            };
            DialogResult result = folder.ShowDialog(IntPtr.Zero);
            if (result.Equals(DialogResult.OK))
                MessageBox.Show(folder.SelectedPath + " Paths:" + folder.SelectedPaths.Length);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top