Как настроить OpenFileDialog для выбора папок? - PullRequest
243 голосов
/ 27 августа 2008

В VS .NET, когда вы выбираете папку для проекта, отображается диалоговое окно, которое выглядит как OpenFileDialog или SaveFileDialog, но настроено на прием только папок. С тех пор как я увидел это, я хотел знать, как это делается. Я знаю о FolderBrowserDialog, но мне никогда не нравился этот диалог. Он начинается слишком мало и не позволяет мне воспользоваться возможностью набирать путь.

Я почти уверен, что сейчас нет способа сделать это из .NET, но мне так же любопытно, как вы делаете это и из неуправляемого кода. Если не считать полного переопределения диалога с нуля, как вы измените диалог, чтобы иметь такое поведение?

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

Это не специфичная для Vista вещь; Я видел этот диалог начиная с VS .NET 2003, поэтому его можно использовать в Win2k и WinXP. Это не вопрос «я хочу знать, как правильно это сделать», а вопрос «мне было любопытно с тех пор, как я впервые захотел сделать это в VS 2003». Я понимаю, что в файловом диалоге Vista есть возможность сделать это, но он работает в XP, поэтому я знаю, что они сделали что-то , чтобы заставить его работать. Ответы, специфичные для Vista, не являются ответами, потому что Vista не существует в контексте вопроса.

Обновление: я принимаю ответ Скотта Вишневского, потому что он идет с рабочим образцом, но я думаю, что Серж заслуживает похвалы за указание на настройку диалога (что, по общему признанию, неприятно из .NET, но делает работа) и Марка Рэнсома для выяснения, что MS, вероятно, развернула специальный диалог для этой задачи.

Ответы [ 17 ]

56 голосов
/ 05 февраля 2009

У меня есть диалог, который я написал, называемый диалогом OpenFileOrFolder, который позволяет вам открывать папку или файл.

Если вы установите для его значения AcceptFiles значение false, он будет работать только в режиме принятия папки.

Вы можете скачать исходники с GitHub здесь

48 голосов
/ 15 февраля 2011

Существует Windows Code Code Pack. У него много вещей, связанных с оболочкой, включая класс CommonOpenFileDialog (в пространстве имен Microsoft.WindowsAPICodePack.Dialogs). Это идеальное решение - обычный открытый диалог с отображением только папок.

Вот пример того, как его использовать:

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

К сожалению, Microsoft больше не поставляет этот пакет, но несколько человек неофициально загрузили двоичные файлы в NuGet. Один пример можно найти здесь . Этот пакет - просто материал для оболочки. Если вам это нужно, у этого же пользователя есть несколько других пакетов, которые предлагают больше функциональных возможностей, присутствующих в оригинальном пакете.

47 голосов
/ 09 марта 2009

Вы можете использовать FolderBrowserDialogEx - повторно используемая производная от встроенного FolderBrowserDialog. Этот позволяет вам ввести путь, даже путь UNC. Вы также можете просматривать компьютеры или принтеры с ним. Работает так же, как встроенный FBD, но ... лучше.

(РЕДАКТИРОВАТЬ: я должен был указать, что этот диалог может быть установлен для выбора файлов или папок.)

Полный исходный код (один короткий модуль 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;
}
34 голосов
/ 04 февраля 2009

Пакет Ookii.Dialogs содержит управляемую оболочку вокруг диалогового окна браузера новой папки (в стиле Vista). Он также изящно ухудшается в старых операционных системах.

27 голосов
/ 27 августа 2008

Лучше использовать для этого FolderBrowserDialog.

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}
23 голосов
/ 09 июня 2013

После нескольких часов поиска я нашел этот ответ от leetNightShade до рабочего решения .

Я полагаю, что есть три вещи, которые делают это решение намного лучше, чем все остальные.

  1. Прост в использовании. Требуется только включить два файла (которые в любом случае можно объединить в один) в вашем проекте.
  2. Возвращается к стандартному FolderBrowserDialog при использовании на XP или более старых системах.
  3. Автор предоставляет разрешение на использование кода для любых целей, которые вы считаете нужными.

    Нет такой лицензии как таковой, которую вы можете взять и сделать с кодом так, как хотите.

Скачать код здесь .

17 голосов
/ 03 февраля 2009

ОК, позвольте мне попробовать подключить первую точку ;-) Немного поиграв со Spy ++ или Winspector, вы увидите, что текстовое поле «Папка» в папке «Расположение проекта VS» является настройкой стандартного диалога. Это не то же самое поле, что и текстовое поле имени файла в стандартном диалоговом окне, например в Блокноте.

С этого момента, я полагаю, VS скрывает текстовые поля / комбинированные списки имен файлов и типов файлов и использует собственный шаблон диалога, чтобы добавить свою собственную часть в нижней части диалога.

РЕДАКТИРОВАТЬ: Вот пример такой настройки и как это сделать (в Win32. Не .NET):

m_ofn - это структура OPENFILENAME, которая лежит в основе диалогового окна файла. Добавьте эти 2 строки:

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

где IDD_FILEDIALOG_IMPORTXLIFF - это пользовательский шаблон диалога, который будет добавлен внизу диалога. Смотрите часть в красном ниже. alt text
(источник: apptranslator.com )

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

Но как мы избавимся от некоторых элементов управления в стандартной части диалога, я не знаю.

Подробнее в этой статье MSDN .

17 голосов
/ 04 февраля 2009

Точное аудио копирование работает в 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, чтобы дать ему такую ​​возможность. Мое решение или что-то подобное будет настолько близко, насколько вы сможете, если только вы не захотите написать свое собственное с нуля.

10 голосов
/ 05 февраля 2009

Вы можете использовать такой код

  • Фильтр скрытия файлов
  • Имя файла скрыть первый текст

Для расширенного скрытия текстового поля для имени файла вам нужно посмотреть на OpenFileDialogEx

Код:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}
10 голосов
/ 04 февраля 2009

Вы можете создать подкласс файлового диалога и получить доступ ко всем его элементам управления. У каждого есть идентификатор, который можно использовать для получения дескриптора окна. Затем вы можете показать и скрыть их, получать от них сообщения об изменениях выбора и т. Д. И т. Д. Все зависит от того, сколько усилий вы хотите предпринять.

Мы сделали это с помощью поддержки классов WTL и настроили диалоговое окно файла, включив в него панель пользовательских мест и подключаемые представления COM.

MSDN предоставляет информацию о том, как сделать это с помощью Win32, эта статья CodeProject включает в себя пример и эта статья CodeProject предоставляет пример .NET .

...