Como usar o OpenFileDialog para selecionar uma pasta?

297

Como usar OpenFileDialogpara selecionar pastas?

Eu usaria o seguinte projeto: https://github.com/scottwis/OpenFileOrFolderDialog

No entanto, enfrentei um problema. Ele usa a GetOpenFileNamefunção e a OPENFILENAMEestrutura. E OPENFILENAMEtem o membro nomeado templateID. É o identificador para o modelo de diálogo. E o projeto contém o res1.rcarquivo e a caixa de diálogo de modelo init também. Mas não consegui descobrir como anexar esse arquivo ao meu projeto c #.

Existe uma maneira melhor de usar um OpenFileDialogpara selecionar pastas?

Yun
fonte
Se você abrir o arquivo do projeto com o editor, notará algumas propriedades adicionais na parte inferior: <VCIncludePath ...>, <Win32Resource ...> e <Target Name = "BeforeBuild" ...>. Você verá que ele executa o rc.exe para compilar o arquivo de recurso res1.rc (certifique-se de copiar o "resource.h" também no seu projeto). Verifique se o VisualC está instalado e se o VCIncludePath aponta para um local adequado (o do github aponta para a versão VC9.0, e pode ser necessário alterá-lo). Após compilar o arquivo .rc, o arquivo .res resultante é adicionado como recurso para o seu executável com a diretiva Win32Resource.
mistika
3
Há uma solução hackish usando OpenFileDialog onde ValidateNamese CheckFileExistssão definidas como false e FileNameé dado um valor simulado para indicar que um diretório é selecionado. Eu digo hack porque é confuso para os usuários sobre como selecionar uma pasta. Veja Selecione o arquivo ou pasta a partir da mesma caixa de diálogo
Daniel Ballinger
1
Thanx Dan, por apontar para o OpenFileDialog-Hack! Isso é muito melhor que o FolderBrowserDialog, porque o OFD mostra pastas marcadas com marcadores, etc., para que todos - especialmente em empresas maiores - descubram. FBD não fará muito bem nesses lugares.
JayC667
1
@ComradeJoecool converti meu comentário para uma resposta . Eu tentei várias vezes e não tive um problema "arquivo não encontrado". Você está reutilizando a mesma instância do OpenFileDialog?
Daniel Ballinger
1
@DanielBallinger ah, eu encontrei o meu problema, desde que eu estou usando o PowerShell para criar o diálogo, a criação ValidateNamese CheckFileExistspara falsenão estava funcionando, eu precisava para configurá-los para 0(ou aprender PowerShell melhor)
ComradeJoecool

Respostas:

397

Basicamente, você precisa da FolderBrowserDialogclasse:

Solicita que o usuário selecione uma pasta. Essa classe não pode ser herdada.

Exemplo:

using(var fbd = new FolderBrowserDialog())
{
    DialogResult result = fbd.ShowDialog();

    if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
    {
        string[] files = Directory.GetFiles(fbd.SelectedPath);

        System.Windows.Forms.MessageBox.Show("Files found: " + files.Length.ToString(), "Message");
    }
}

Se você trabalha no WPF, precisa adicionar a referência System.Windows.Forms.

você também tem que adicionar using System.IOpara a Directoryaula

Ionică Bizău
fonte
186
O FolderBrowserDialog não possui usabilidade. A principal desvantagem é que ele não permite copiar um caminho de pasta do Windows Explorer para navegação rápida, tornando-o inútil quando você precisa detalhar mais de três níveis. A perfuração em cada pasta não é desejada, especialmente quando o armazenamento é lento ou quando há muitas pastas em um dos níveis.
mistika
2
A pergunta é especificamente sobre como usar o OpenFileDialog (OFD) para selecionar uma pasta, não o FolderBrowserDialog (FBD). Concordo que o FBD é horrível do ponto de vista do usuário.
Michael Paulukonis
27
Como alternativa a este diálogo com UI quebrado, usar um CommonOpenFileDialog : new CommonOpenFileDialog { IsFolderPicker = true }.
ANeves
114
Por favor, nunca use ! Lembro-me como usuário culpando esses pobres programadores que criaram outro aplicativo com essa terrível caixa de diálogo de exibição em árvore (que é apenas o FolderBrowserDialog) . É completamente inutilizável: um monte de diretórios raiz, um painel de favoritos ausente e o mais horrível - você não pode nem colar um caminho lá! E agora como programador, vejo um conselho para usá-lo ... Por favor, não faça isso.
Hi-Angel
2
O FolderBrowserDialog tem uma grande falha, além de tudo o que os outros usuários disseram. Não lembra o último caminho selecionado!
AleX_
254

Como uma observação para futuros usuários que gostariam de evitar o uso FolderBrowserDialog, a Microsoft lançou uma API chamada WindowsAPICodePack que tinha uma caixa de diálogo útil chamada CommonOpenFileDialog, que poderia ser configurada em um IsFolderPickermodo. A API está disponível na Microsoft como um pacote NuGet .

Isso é tudo o que eu precisava para instalar e usar o CommonOpenFileDialog. (NuGet lidou com as dependências)

Install-Package Microsoft.WindowsAPICodePack-Shell

Para a linha de inclusão:

using Microsoft.WindowsAPICodePack.Dialogs;

Uso:

CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
    MessageBox.Show("You selected: " + dialog.FileName);
}
Joe
fonte
36
Acho que esta é a resposta mais próxima de "Como usar o OpenFileDialog para selecionar uma pasta?" O FolderBrowseDialog é muito inutilizável. Obrigado por esta resposta.
precisa
46
Essa deve ser a resposta. E observe que você precisa instalar o Microsoft.WindowsAPICodePack.Shellpacote através do NuGet antes de poder usá-lo CommonOpenFileDialog.
smwikipedia
1
Se você usar isso com o VS2017, ele reinicia sua janela principal.
Lokiare 10/08/18
1
Nota para os FolderBrowserDialogusuários: o uso de várias instâncias simultâneas pode criar problemas. Isso CommonOpenFileDialogé melhor
Alper
9
Microsoft parece ter republicado-lo comoWindowsAPICodePack-Shell
NucS
32

Há uma solução hackish usando OpenFileDialogwhere ValidateNamese CheckFileExistssão ambos configurados como false e FileNamerecebe um valor simulado para indicar que um diretório está selecionado.

Eu digo hack porque é confuso para os usuários sobre como selecionar uma pasta. Eles precisam estar na pasta desejada e pressione Abrir enquanto o nome do arquivo diz "Seleção de Pasta".

Caixa de diálogo de seleção de pasta C #

Isso se baseia em Selecionar arquivo ou pasta na mesma caixa de diálogo de Denis Stankovski.

OpenFileDialog folderBrowser = new OpenFileDialog();
// Set validate names and check file exists to false otherwise windows will
// not let you select "Folder Selection."
folderBrowser.ValidateNames = false;
folderBrowser.CheckFileExists = false;
folderBrowser.CheckPathExists = true;
// Always default to Folder Selection.
folderBrowser.FileName = "Folder Selection.";
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
    string folderPath = Path.GetDirectoryName(folderBrowser.FileName);
    // ...
}
Daniel Ballinger
fonte
Entendo, sim, consegui funcionar. Uma coisa irritante é que Folder Selection.será pregada no final do nome do arquivo da seguinte maneira: C:\Folder Selection.acho que você sempre pode remover esses caracteres da string. Ainda parece melhor do que o FolderBrowserDialog
CamaradaJoecool
Isso não funciona para mim. Não me permitirá selecionar pastas. Apenas os abre.
Lokiare 10/08/1918
1
@Lokiare Isso foi o que eu quis dizer quando disse que era um hack. Veja as instruções do segundo parágrafo.
Daniel Ballinger
2
@ComradeJoecool, você não precisa removê-lo manualmente. é para isso que serve a última linha do código: string folderPath = Path.GetDirectoryName (folderBrowser.FileName);
Heriberto Lugo
Oh! existe um problema com este método: se o usuário pressionar os botões Para cima ou Para trás ao navegar pelas pastas, o Openbotão principal da caixa de diálogo não funcionará conforme o esperado! isso faz você voltar para a pasta anterior! mas funciona quando você apenas clique duas vezes em pastas para selecioná-los ou selecione alguns arquivos dentro de cada pasta (se houver qualquer arquivo que você pode escolher)
S.Serpooshan
14

Estranho que tantas respostas / votos, mas ninguém adicione o seguinte código como resposta:

using (var fldrDlg = new FolderBrowserDialog())
{ 
    //fldrDlg.Filter = "Png Files (*.png)|*.png";
    //fldrDlg.Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"

    if (fldrDlg.ShowDialog() == DialogResult.OK)
    {
        //fldrDlg.SelectedPath -- your result
    }
}
Andrew
fonte
9
Existe alguma diferença entre a sua resposta e a @ Ionică Bizău Answer ?
Chetan Mehra
1
A lógica é a mesma, mas minha resposta é muito mais curta e você não precisa criar uma variável extra para o DialogResult.
Andrew Andrew
2
Como já mencionado, existem alguns grandes problemas com este método: este é um péssimo diálogo de exibição em árvore! você não pode copiar e colar um caminho para ele, precisa perfurar um a um a partir da pasta raiz e não há painel de favoritos!
precisa saber é o seguinte
@ S.Serpooshan não importa. Este é apenas um exemplo de uso de QUALQUER caixa de diálogo. Você pode usar qualquer outra caixa de diálogo, se desejar. :)
Andrew
9

Parece-me que você está logo após o FolderBrowserDialog .

Simon Whitehead
fonte
5
Eu acho que isso está ficando com o voto negativo, porque o FolderBrowserDialog tem uma usabilidade horrível e o OP queria explicitamente usar o OpenFileDialog.
Mbx19 /
3
@mbx Talvez. Para ser justo, o OP não diz "Não posso usar nada além do OpenFileDialog". Quando eu respondi isso originalmente (há mais de quatro anos e meio ...), a suposição era que o OP simplesmente não sabia como permitir que um usuário abrisse uma pasta. Na verdade, eu não retornei a essa pergunta depois de postar esta resposta, portanto não vi nenhuma discussão sobre usabilidade - nem a considerei ao responder.
Simon Whitehead
6

Aqui está outra solução, que tem toda a fonte disponível em um único arquivo ZIP simples.

Ele apresenta o OpenFileDialog com sinalizadores adicionais do Windows que o fazem funcionar como o diálogo de seleção de pasta do Windows 7+.

De acordo com o site, é de domínio público: "Não há licença, pois você é livre para pegar e fazer com o código o que quiser".

Links do Archive.org:

Ben Keene
fonte
1
Funciona perfeitamente! Além disso, você pode selecionar várias pastas adicionando esta linha em "FolderSelectDialog.cs": public string [] FileNames {get {return ofd.FileNames; }} e mude ofd.Multiselect = true; no construtor
Maxter
5

Dê uma olhada nas bibliotecas Ookii Dialogs, que possuem uma implementação de uma caixa de diálogo do navegador de pastas para Windows Forms e WPF, respectivamente.

insira a descrição da imagem aqui

Ookii.Dialogs.WinForms

https://github.com/augustoproiete/ookii-dialogs-winforms


Ookii.Dialogs.Wpf

https://github.com/augustoproiete/ookii-dialogs-wpf

C. Augusto Proiete
fonte
Boa. Nota: Ookii.Dialogs requer o Microsoft .NET Framework 4.5 ou superior. (não pode ser usado em WinXP)
S.Serpooshan
2
@ S.Serpooshan - Bem, acho que também não funcionará no meu PC com Windows 3.1, certo? Mas sério, em 2018, ninguém deveria pensar no Windows XP de qualquer maneira - está morto há muito tempo.
rory.ap
@ rory.ap, na verdade, o principal problema desta solução para mim é que ela não mostra os arquivos ao procurar por pastas. Às vezes, é muito útil poder ver os arquivos (por exemplo, imagens a serem processadas) quando o usuário deseja selecionar a pasta!
precisa saber é o seguinte
-5

essa deve ser a maneira mais óbvia e direta

using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{

   System.Windows.Forms.DialogResult result = dialog.ShowDialog();

   if(result == System.Windows.Forms.DialogResult.OK)
   {
      selectedFolder = dialog.SelectedPath;
   }

}
AHM
fonte
3
FolderBrowserDialogjá foi oferecido aqui várias vezes e é a resposta errada. É uma interface desatualizada e muito descomplicada. Ele usa SHBrowseForFolderpor baixo e até os documentos afirmam "Para Windows Vista ou posterior, é recomendável usar IFileDialogcom a FOS_PICKFOLDERSopção em vez da SHBrowseForFolderfunção. Isso usa a caixa de diálogo Abrir arquivos no modo de seleção de pastas e é a implementação preferida".
Herohtar 22/11/19