Pergunta

Como posso apresentar ao usuário um controle que lhe permita selecionar um diretório?

Não parece haver nenhum controle nativo .net que faça isso?

Foi útil?

Solução

O FolderBrowserDialog classe é a melhor opção.

Outras dicas

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

Nota: não há garantia de este código irá funcionar em futuras versões do framework .Net. Usando internos do .NET Framework privadas como feito aqui através da reflexão provavelmente não é bom no geral. Use a solução de interoperabilidade mencionado na parte inferior, como a API do Windows é menos provável de mudança.

Se você está procurando um seletor de pasta que se parece mais com o diálogo do Windows 7, com a capacidade de copiar e colar de uma caixa de texto na parte inferior eo painel de navegação à esquerda com favoritos e locais comuns, então você pode obter acesso a isso de uma maneira muito leve.

A interface do usuário FolderBrowserDialog é muito mínima:

 enter descrição da imagem aqui

Mas você pode ter este em vez disso:

 enter descrição da imagem aqui

Aqui está uma classe que abre um seletor de pasta Vista estilo usando a interface IFileDialog privada .Net, sem diretamente usando interoperabilidade no código (.Net cuida disso para você). Ele cai de volta para a caixa de diálogo de pré-Vista se não em uma versão de alta do Windows suficiente. Deve funcionar no Windows 7, 8, 9, 10 e superior (teoricamente).

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; } }
        }
    }
}

Eu desenvolvi isso como uma versão limpa do .NET Win 7-style pasta seleta de diálogo por Bill Seddon de lyquidity.com (não tenho filiação). Eu escrevi o meu próprio porque a sua solução requer uma classe de reflexão adicional que não é necessária para este fim focado, usa o controle de fluxo baseado em exceção, não armazena em cache os resultados de suas chamadas de reflexão. Note-se que a classe VistaDialog estática aninhada é para que suas variáveis ??reflexão estáticos não tente se preenchida se o método Show nunca é chamado.

É usado como assim em um formulário do Windows:

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

Pode, claro, brincar com as suas opções e quais propriedades ele expõe. Por exemplo, ele permite que multiselect na caixa de diálogo Vista de estilo.

Além disso, observe que Simon Mourier deu uma resposta que mostra como fazer exatamente o mesmo trabalho usando interoperabilidade contra o API do Windows diretamente, embora sua versão teria que ser completado para usar o diálogo estilo antigo se em uma versão mais antiga do Windows. Infelizmente, eu não tinha encontrado o seu post ainda quando eu trabalhei a minha solução. Nome do seu veneno!

Você poderia usar apenas a classe FolderBrowserDialog do namespace System.Windows.Forms.

Por favor, não tentar rolar o seu próprio com uma classe TreeView / DirectoryInfo. Por um lado há muitos agradável características que você consegue de graça (ícones / clique com o botão direito / redes) usando SHBrowseForFolder. Por outro, existem casos de ponta / pega você provavelmente não vai estar ciente.

Você pode usar uma TreeView em combinação com a classe DirectoryInfo.

Para muita funcionalidade mais do que o FolderBrowserDialog, como filtragem, caixas de seleção, etc, dê uma olhada controles 3o partido como Shell MegaPack . Uma vez que eles são controles, para que eles possam ser colocados em seus próprios formulários em vez de aparecer como um diálogo modal.

ou até mais melhor, você pode colocar esse código em um arquivo de classe

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);

}

E usá-lo como este

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

a melhor maneira de fazê-lo e com a seleção de pasta múltiplos

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] });
            }
        }
    }
}

uso:

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top