Как использовать OpenFileDialog для выбора папки?

297

Как использовать OpenFileDialogдля выбора папок?

Я собирался использовать следующий проект: https://github.com/scottwis/OpenFileOrFolderDialog

Однако я столкнулся с одной проблемой. Он использует GetOpenFileNameфункцию и OPENFILENAMEструктуру. И OPENFILENAMEназвал члена templateID. Это идентификатор шаблона диалога. И проект содержит res1.rcфайл и шаблонный диалог init тоже. Но я не мог понять, как прикрепить этот файл к моему проекту на C #.

Есть ли лучший способ использовать OpenFileDialogдля выбора папки?

Yun
источник
Если вы откроете файл проекта в редакторе, вы заметите некоторые дополнительные свойства внизу: <VCIncludePath ...>, <Win32Resource ...> и <Target Name = "BeforeBuild" ...>. Вы увидите, что он запускает rc.exe для компиляции файла ресурсов res1.rc (обязательно скопируйте файл «resource.h» тоже в свой проект). Убедитесь, что у вас установлен VisualC и что VCIncludePath указывает на правильное местоположение (github указывает на версию VC9.0, и вам может потребоваться изменить ее). После компиляции файла .rc полученный файл .res добавляется в качестве ресурса для вашего исполняемого файла с помощью директивы Win32Resource.
Мистика
3
Существует хакерское решение, использующее OpenFileDialog, где ValidateNamesи CheckFileExistsоба имеют значение false, и FileNameему дается фиктивное значение, чтобы указать, что каталог выбран. Я говорю хак, потому что это сбивает с толку пользователей о том, как выбрать папку. См. Выбор файла или папки из того же диалогового окна
Даниэль Баллинджер,
1
Спасибо Дану за указание на OpenFileDialog-Hack! Это намного лучше, чем FolderBrowserDialog, потому что OFD показывает папки с закладками и т. Д., Поэтому каждый - особенно в крупных компаниях - находит свое дерьмо. FBD не принесет много пользы в этих местах.
JayC667
1
@ComradeJoecool Я преобразовал свой комментарий в ответ . Я пробовал это несколько раз, и у меня не было проблемы "файл не найден". Вы повторно используете тот же экземпляр OpenFileDialog?
Даниэль Баллинджер
1
@DanielBallinger ах, я нашел свою проблему, так как я использую Powershell для создания диалога, настройки ValidateNamesи CheckFileExistsчтобы falseон не работал, мне нужно было установить их 0(или лучше изучить powershell)
ComradeJoecool

Ответы:

397

В основном вам нужен FolderBrowserDialogкласс:

Предлагает пользователю выбрать папку. Этот класс не может быть унаследован.

Пример:

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

Если вы работаете в WPF, вы должны добавить ссылку на System.Windows.Forms.

Вы также должны добавить using System.IOдля Directoryкласса

Ионика Бизэу
источник
186
В FolderBrowserDialog отсутствует удобство использования. Основным недостатком является то, что он не позволяет копировать путь к папке из Проводника Windows для быстрой навигации, что делает его бесполезным, когда вам необходимо детализировать более трех уровней. Детализация в каждой папке нежелательна, особенно когда хранилище медленное или когда у вас много папок на одном из уровней.
Мистика
2
Вопрос конкретно об использовании OpenFileDialog (OFD) для выбора папки, а не FolderBrowserDialog (FBD). Я согласен, что FBD ужасен с точки зрения пользователя.
Майкл Паукуонис
27
В качестве альтернативы к этому диалогу с разбитой UI, используйте CommonOpenFileDialog : new CommonOpenFileDialog { IsFolderPicker = true }.
Ноябрь
114
Пожалуйста, никогда не используйте его ! Я помню, как пользователь, я обвинял этих бедных программистов, которые сделали еще одно приложение с этим ужасным диалоговым окном в виде дерева (которое является просто FolderBrowserDialog) . Это совершенно непригодно: куча корневых папок, недостающая панель избранного и самое ужасное - вы даже не можете вставить туда путь! И теперь, как программист, я вижу совет использовать его ... Пожалуйста, не делайте этого.
Привет, Ангел,
2
У FolderBrowserDialog есть один большой недостаток помимо всего остального, что сказали другие пользователи. Он не помнит последний выбранный путь!
AleX_
254

В качестве заметки для будущих пользователей, которые хотели бы отказаться от использования FolderBrowserDialog, Microsoft однажды выпустила API под названием WindowsAPICodePack, в котором есть полезный диалог CommonOpenFileDialog, который можно установить в IsFolderPickerрежим. API доступен от Microsoft в виде пакета NuGet .

Это все, что мне нужно для установки и использования CommonOpenFileDialog. (NuGet обработал зависимости)

Install-Package Microsoft.WindowsAPICodePack-Shell

Для строки включения:

using Microsoft.WindowsAPICodePack.Dialogs;

Использование:

CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
    MessageBox.Show("You selected: " + dialog.FileName);
}
Джо
источник
36
Я думаю, что это ближайший ответ на вопрос «Как использовать OpenFileDialog для выбора папки?» FolderBrowseDialog очень непригоден для использования. Спасибо за этот ответ.
Корай
46
Это должно быть ответом. И обратите внимание, что вам нужно установить Microsoft.WindowsAPICodePack.Shellпакет через NuGet, прежде чем вы сможете использовать это CommonOpenFileDialog.
smwikipedia
1
Если вы используете это с VS2017, это рестайлинг вашего главного окна.
Локиаре
1
Примечание для FolderBrowserDialogпользователей: одновременное использование нескольких экземпляров может создать проблемы. Это CommonOpenFileDialogлучше
Альпер
9
Microsoft, кажется, переиздал это какWindowsAPICodePack-Shell
NucS
32

Существует хакерское решение, использующее OpenFileDialogгде ValidateNamesи CheckFileExistsоба имеют значение false, и FileNameему дается фиктивное значение, чтобы указать, что каталог выбран.

Я говорю хак, потому что это сбивает с толку пользователей о том, как выбрать папку. Они должны находиться в нужной папке, а затем просто нажать «Открыть», а имя файла говорит «Выбор папки».

Диалог выбора папки C #

Это основано на Выбрать файл или папку из того же диалога Дениса Станковского.

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);
    // ...
}
Дэниел Баллинджер
источник
Я вижу, да, я получил это работает. Одна раздражающая вещь заключается в том, что Folder Selection.она будет добавлена ​​в конец имени файла, например, так: C:\Folder Selection.я думаю, вы всегда можете удалить эти символы из строки. По-прежнему выглядит лучше, чем FolderBrowserDialog
ComradeJoecool
Это не работает для меня. Это не позволит мне выбрать папки. Это просто открывает их.
Локиаре
1
@Lokiare Вот что я имел в виду, когда сказал, что это взлом. Смотрите инструкции из второго абзаца.
Даниэль Баллинджер
2
@ComradeJoecool, вам не нужно вручную удалять это вручную. Вот для чего предназначена последняя строка в коде: string folderPath = Path.GetDirectoryName (folderBrowser.FileName);
Хериберто Луго
Ой! Существует проблема с этим методом: если пользователь нажимает кнопки « Вверх» или « Назад» при просмотре папок, главная Openкнопка диалога не работает должным образом! это потому что вы возвращаетесь в предыдущую папку! но это работает, когда вы просто дважды щелкаете папки, чтобы выбрать их или выбрать несколько файлов внутри каждой папки (если есть какой-либо файл, который вы можете выбрать)
S.Serpooshan
14

Странно, что столько ответов / голосов, но никто не добавляет следующий код в качестве ответа:

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
    }
}
Андрей
источник
9
Есть ли разница между вашим ответом и @ Ionică Bizau Answer ?
Четан Мехра
1
Логика та же, но мой ответ намного короче, и вам не нужно создавать дополнительную переменную для DialogResult.
Андрей
2
Как уже упоминалось, у этого метода есть некоторые большие проблемы: это ужасный диалог в виде дерева! Вы не можете скопировать и вставить путь к нему, вы должны сверлить по одному из корневой папки, и нет панели избранного!
С.Серпушан
@ S.Serpooshan это не имеет значения. Это всего лишь пример использования ЛЮБОГО диалога. Вы можете использовать любой другой диалог, если хотите. :)
Андрей
9

Звучит так, будто вы только после FolderBrowserDialog .

Саймон Уайтхед
источник
5
Я предполагаю, что это получает отрицательную оценку b / c (как уже указала мистика), FolderBrowserDialog имеет ужасное удобство использования, и OP явно хотел использовать OpenFileDialog.
mbx
3
@mbx Возможно. Честно говоря, OP не говорит: «Я не могу использовать ничего, кроме OpenFileDialog». Когда я первоначально ответил на это (более 4 с половиной лет назад ...), предполагалось, что ОП просто не знает, как позволить пользователю открыть папку. На самом деле я не вернулся к этому вопросу после публикации этого ответа, поэтому я не видел ни одной дискуссии о юзабилити - и я не учел ее при ответе.
Саймон Уайтхед
6

Вот еще одно решение, в котором весь источник доступен в одном простом ZIP-файле.

Он представляет OpenFileDialog с дополнительными флагами Windows, что делает его похожим на диалог выбора папок Windows 7+.

На сайте это общественное достояние: «Там нет лицензии как таковой, так как вы можете взять и делать с кодом то, что вы будете».

Ссылки на Archive.org:

Бен Кин
источник
1
Работай отлично! Также вы можете выбрать несколько папок, добавив эту строку в «FolderSelectDialog.cs»: public string [] FileNames {get {return ofd.FileNames; }} и change ofd.Multiselect = true; в конструкторе
Maxter
5

Взгляните на библиотеки Ookii Dialogs, в которых реализован диалог браузера папок для Windows Forms и WPF соответственно.

введите описание изображения здесь

Ookii.Dialogs.WinForms

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


Ookii.Dialogs.Wpf

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

К. Аугусто Проиете
источник
хорошо. примечание: Ookii.Dialogs требует Microsoft .NET Framework 4.5 или выше. (нельзя использовать в WinXP)
S.Serpooshan
2
@ S.Serpooshan - Ну, я думаю, это не будет работать и на моем ПК с Windows 3.1, верно? А если серьезно, в 2018 году никто не должен думать о Windows XP в любом случае - она ​​давно умерла.
rory.ap
@ rory.ap на самом деле, главная проблема этого решения для меня заключается в том, что он не показывает файлы при просмотре папок. Иногда очень полезно иметь возможность просматривать файлы (например, изображения для обработки), когда пользователь хочет выбрать папку!
С.Серпушан
-5

это должен быть самый очевидный и прямой путь

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
источник
3
FolderBrowserDialogуже предлагался здесь несколько раз, и это неправильный ответ. Это устаревший и не очень удобный интерфейс. Он использует SHBrowseForFolderнижнюю часть и даже состояние документов: «Для Windows Vista или более поздней версии рекомендуется использовать IFileDialogс этой FOS_PICKFOLDERSопцией, а не с SHBrowseForFolderфункцией. Это использует диалог« Открыть файлы »в режиме выбора папок и является предпочтительной реализацией».
Herohtar