Як налаштувати OpenFileDialog для вибору папок?


251

У VS .NET, коли ви вибираєте папку для проекту, відображається діалогове вікно, схоже на OpenFileDialog або SaveFileDialog, але налаштоване приймати лише папки. З тих пір, як я це бачив, я хотів знати, як це робиться. Мені відомо про FolderBrowserDialog, але мені ніколи не сподобався цей діалог. Він починається занадто малим, і не дозволяє мені скористатися можливістю ввести шлях.

Я майже впевнений, що зараз немає способу зробити це з .NET, але мені так само цікаво, як це зробити і з некерованого коду. Якщо повністю не повторно реалізувати діалогове вікно з нуля, як ви модифікуєте діалог таким чином?

Я також хотів би ще раз зазначити, що мені відомо про FolderBrowserDialog, але іноді мені не подобається його використовувати, крім того, що мені справді цікаво, як налаштувати діалог таким чином. Якщо мені сказати, що я просто використовую FolderBrowserDialog, це допомагає мені підтримувати постійний досвід користувальницького інтерфейсу, але не задовольняє мою цікавість, тому це не вважатиметься відповіддю.

Це не специфічна для Vista річ; Я бачив це діалогове вікно з VS .NET 2003, тому це можливо в Win2k та WinXP. Це менше питання "Я хочу знати правильний спосіб зробити це" питання, і більше "Мені цікаво про це з тих пір, як я вперше хотів це зробити в VS 2003" питання. Я розумію, що у діалоговому вікні файлу Vista є можливість це зробити, але він працює в XP, тому я знаю, що вони щось зробили, щоб змусити його працювати. Відповіді для Vista не є відповідями, оскільки Vista не існує в контексті запитання.

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


7
просто просте рішення з codeproject codeproject.com/Articles/44914/… [Ключовим словом для отримання OpenFileDialog для вибору обох файлів і папок є встановлення властивостей ValidateNames і CheckFileExists на false (dialog.ValidateNames = false; dialog.CheckFileExists = false) і встановіть FileName для якогось спеціального ключового слова, щоб переконатися, що папки вибрані (dialog.FileName = "Вибір папки";).]
Riju

3
Подайте це як відповідь, це зробило роботу для мого проекту.
CigarDoug

@Riju, dialog.FileName = "Folder Selection"мабуть, буде dialog.FileName = "Folder Selection."з останнім періодом? у будь-якому випадку я не можу змусити його працювати в силі на другому клацанні "Відкрити" в будь-якому випадку.
Продовжує

nvm, в powerhell налаштуванні dialog.CheckFileExists = 0замість помилкового вирішили мою проблему
ComradeJoecool

Відповіді:


57

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

Якщо встановити його значення AcceptFiles значення false, воно працює лише в режимі прийняття папок.

Ви можете завантажити джерело з GitHub тут


4
Дуже цікаво і, безумовно, так складно, як я зрозумів. Будь-який шанс анотувати його та вказати, що це робить? Це разом з іншими коментарями приводить мене до думки, що MS, ймовірно, просто згорнула свій власний діалог.
OwenP

1
Я отримую таку помилку при спробі побудувати своє рішення ... на жаль, c ++ не в одній із моїх сильних сторін ... Помилка 1 не може відкритися, включаючи файл 'afxres.h'
Ігнасіо Солер Гарсія

1
@SoMoS та інші з тією ж проблемою: у файлі WindowsFormsApplication1.csproj редагуйте рядок 100, щоб вона відповідала вашим налаштуванням. У моєму випадку мені довелося змінити "9.0" на "10.0" (двічі) та видалити "(x86)" (двічі).
RenniePet

2
Я завантажив код (zip) і знайшов .h (C) файл у, і компілював з помилкою, наприклад, не вдається відкрити, включати файл 'sal.h'.
Лей Ян

2
Це рішення також не працює на VS2010 та VS2017!
AleX_

49

Ви можете використовувати FolderBrowserDialogEx - повторно використовувану похідну вбудованого FolderBrowserDialog. Цей дозволяє вводити шлях, навіть UNC шлях. Ви також можете переглядати комп’ютери чи принтери з ним. Працює так само, як і вбудований FBD, але ... краще.

(EDIT: я мав би зазначити, що це діалогове вікно можна встановити для вибору файлів або папок.)

Повний вихідний код (один короткий модуль 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;
}

7
Вибачте, якщо я образився, мені просто шкода задати питання і прописати «Я хочу цю конкретну річ, а не інші речі», і люди з радістю пропонують не запитувану річ. Я хотів діалогового вікна браузера файлів, а не діалогового вікна браузера папок.
OwenP

15
Як формулюється питання, мені здається, що він запитує діалогове вікно вибору папок - це не так? У всякому разі, це саме те, що я шукав +1
Тім

Однозначно найкраща відповідь поки що
Василь Попов

1
Це не змінює факт, що відповідь все ще є лише посиланням. Показано, як використовувати код, розміщений на ресурсі поза сайтом, перестає бути корисним, коли це посилання також стає тимчасово або назавжди недоступним. Правила існують з причини, і цей внесок суперечить цим правилам.
Неочікуваний

1
Я переглянув цю відповідь, і вона, мабуть, не посилається на ресурс, що знаходиться поза сайтом Тож "кожна інша відповідь" явно неправильна. Якщо ви відчуваєте, що я перебільшую реакцію, можливо, вам слід порушити питання на мета, щоб обговорити правила. Я не буду. Я просто застосую їх.
Неочікуваний

48

Є пакет кодів Windows API. У ньому багато матеріалів, пов’язаних із оболонкою, включаючи CommonOpenFileDialogклас (у Microsoft.WindowsAPICodePack.Dialogsпросторі імен). Це ідеальне рішення - звичайний відкритий діалог із відображеними лише папками.

Ось приклад того, як його використовувати:

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

На жаль, Microsoft більше не постачає цей пакет, але кілька людей неофіційно завантажили бінарні файли в NuGet. Один приклад можна знайти тут . Цей пакет - це лише специфічні для оболонки речі. Якщо вам це потрібно, той самий користувач має кілька інших пакетів, які пропонують більше функціональних можливостей, наявних у вихідному пакеті.


1
Я не знав, що це в пакеті пакета програм Windows API - дякую, що вказав на це.
Патрік Клюг

10
Клас CommonOpenFileDialog існує лише в Windows Vista або пізніших версіях, тому буде винятком старіші операційні системи
Рейчел

1
Скажіть, будь ласка, як посилатися на пакет коду API API?
jeff

1
Архівну галерею вилучено. або так сказано в посиланні. Чи може це бути новим місцем для нього?
За замовчуванням

3
До речі, клас CommonOpenFileDialog знаходиться в просторі імен Microsoft.WindowsAPICodePack.Dialogs (мені знадобилося деякий час, щоб знайти його).
morgb

35

Пакет Ookii.Dialogs містить керовану обгортку навколо нового діалогового вікна браузера папок (у стилі Vista). Це також виразно деградує на старих операційних системах.


2
Класно, це відкритий код з ліцензією BSD-стилю!
Роман Старков

7
Єдина проблема полягає в тому, що я не дозволю мені використовувати як клієнтський профіль .net Framework.
Кугель

2
Дуже приємне рішення. Це, на мій погляд, найкраща відповідь. Саме те, що я шукав з 3 років.
Самуїл

1
Ще одна проблема з цим рішенням: воно не дозволяє користувачеві вставити неіснуючий шлях. Незначний, порівняно, але все одно шкода.
Роман Старков

1
Найкраща практична відповідь для тих, хто хоче OpenFileDialogдіалог у стилі -style.
аква

27

Краще використовувати для цього FolderBrowserDialog.

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

9
Я знаю, що краще використовувати FolderBrowserDialog. Мені цікаво, як це робилося незалежно. FolderBrowserDialog багато в чому смердить; навіть у Vista він не має місця. Смішно, як якщо це краще, MS поки що уникала цього в 3-х версіях VS.
OwenP

24
FolderBrowserDialog має безліч проблем юзабіліті. Я б не розглядав, як це реально ставити в програму. Перегляньте мій пост для діалогу, який має набагато кращу юзабіліті
Скотт Вісневський

6
FolderBrowserDialog не дозволяє: - вводити / вставляти цілі шляхи в текстове поле внизу - використовувати рядок "Улюблені посилання" на Vista - використовувати пошук у Vista
decasteljau

89
FolderBrowserDialog - це справді жахливий біт інтерфейсу користувача.
mackenir

32
Серйозно, люди, ПРОСТО перестаньте вводити цей дратівливий діалог у ваші програми. Він має ДУЖЕ BAD UI, як підкреслювали попередні коментарі.
Роман Старков

23

Після декількох годин пошуків я знайшов цю відповідь на leetNightShade в вигляді робочого розчину .

Три речі, на мою думку, роблять це рішення набагато кращим, ніж усі інші.

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

    Немає такої ліцензії, як ви вільні брати і робити з кодом те, що вам потрібно.

Завантажте код тут .


@MattDavis: Я підтвердив, що він працює на .NET Framework 4.0 (стандартний та профіль клієнта). Просто переконайтеся, що у проекті додані і FolderSelectDialog.cs, і Reflector.cs. Однак одне ... ви працюєте в Windows 8? Я тестував на комп’ютері Win7.
Алекс Ессільфі

@ Алекс Ессільфі, ти прав. Я, мабуть, зробив щось не так, втягуючи це у свій проект. Раніший коментар я видалю для наочності.
Метт Девіс

Перебігав декілька варіантів і думав, що цей найкращий. Рекомендуюча.
Яєд

Працював у Windows 10 для мене. Гарне просте рішення
Девід Уілтон

доведеться поважати відмову в старих системах
Майк М

17

Точна аудіокопія працює таким чином у 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, щоб надати йому цю можливість. Моє рішення чи щось подібне буде максимально наближеним, якщо ви не готові кодувати власне з нуля.


17

Гаразд, дозвольте спробувати підключити першу крапку ;-) Якщо трохи пограти з Spy ++ або Winspector, видно, що текстове поле «Папка» у розділі VS Project Location - це налаштування стандартного діалогу. Це не те саме поле, що і текстове поле файлу в стандартному діалоговому вікні файлу, наприклад, в Блокноті.

З цього моменту, я думаю, VS приховує ім'я файлу та текстові поля / комбінації файлів і використовує власний шаблон діалогу, щоб додати власну частину в нижній частині діалогового вікна.

EDIT: Ось приклад такої настройки та як це зробити (у Win32. Не .NET):

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

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

де IDD_FILEDIALOG_IMPORTXLIFF - це власний шаблон діалогу, який буде доданий у нижній частині діалогового вікна. Дивіться частину червоного кольору нижче. (джерело: apptranslator.com )alt текст

У цьому випадку спеціальна частина - це лише мітка + гіперпосилання, але це може бути будь-який діалог. Він може містити кнопку ОК, яка дозволила б нам підтвердити вибір лише для папок.

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

Більш докладно в цій статті MSDN .


1
Це звучить як деякі пояснення, які я чув у минулому, але я ніколи не бачив демонстрації концепції. Чи є підказки в документації MSDN про це?
OwenP

10

Ви можете підкласифікувати діалогове вікно файлів та отримати доступ до всіх його елементів управління. Кожен має ідентифікатор, за допомогою якого можна отримати його ручку вікна. Потім ви можете їх показати та заховати, отримати від них повідомлення про зміни вибору тощо. Все залежить від того, скільки зусиль ви хочете докласти.

Ми зробили наше, використовуючи підтримку класу WTL, і налаштували діалогове вікно файлів, щоб включати в себе спеціальну панель місць та перегляд COM-модулів.

MSDN надає інформацію про те, як це зробити за допомогою Win32, ця стаття CodeProject містить приклад , а ця стаття CodeProject надає приклад .NET .


10

Ви можете використовувати такий код

  • Фільтр - це приховати файли
  • Ім'я файлу - це приховати перший текст

Для розширеного приховування текстового поля для імені файлу вам потрібно подивитися OpenFileDialogEx

Код:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

Просте і те, що мені потрібно для Windows 7+
Hao Nguyen

Також потрібен OFN_NOVALIDATE у прапорах
алхімік Гобліна

5

Я припускаю, що ви на Vista використовуєте VS2008? У цьому випадку я думаю, що параметр FOS_PICKFOLDERS використовується при виклику діалогового вікна файлу Vista IFileDialog . Я боюся, що в .NET-коді це буде залучати велику кількість інтегрованих кодів P / Invoke для роботи.


1
Специфічні для Vista; Я вперше побачив це на VS 2003 на Windows XP.
OwenP

2

Перше рішення

Я розробив це як очищену версію діалогового вікна вибору папки у стилі .NET Win 7 Білла Седдона з lyquidity.com (я не маю приналежності). (Я дізнався про його код з іншої відповіді на цій сторінці ). Я написав своє, тому що його рішення потребує додаткового класу Reflection, який не потрібен для цієї цілеспрямованої мети, використовує керований потоком керування потоком, не кешує результати своїх дзвінків на відображення. Зауважте, що вкладений статичний VistaDialogклас такий, що його змінні статичного відображення не намагаються заповнити, якщо Showметод ніколи не викликається. Він повертається до діалогового вікна перед Vista, якщо він не є досить високою версією Windows. Має працювати в Windows 7, 8, 9, 10 і новіших версій (теоретично).

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

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

Він використовується так у формі 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.

Друге рішення

Саймон Мур’є дав відповідь, яка показує, як виконати точно таку ж роботу, використовуючи інтероп безпосередньо проти API Windows, хоча його версію потрібно було б доповнити, щоб використовувати діалог старішого стилю, якщо у старій версії Windows. На жаль, я ще не знайшов його посаду, коли працював над своїм рішенням. Назвіть свою отруту!


Подібний приклад використання для виклику цього тонкого діалогового вікна як діалогового вікна (наприклад, із програм консольного типу) із порожньою ручкою: збирається прямо з поля: var dialog = new FolderSelectDialog {InitialDirectory = "C: \\", Title = "Виберіть a папка для імпорту музики з "}; if (dialog.Show ()) {рядок myFolder = dialog.FileName; }
Філм

Примітка: Мій приклад використання в якості коментаря важко читати, тому: Найважливіша зміна початкового використання "приклад": Використовуйте кому між InitialDirectory і заголовком ..
Philm

1

Спробуйте це з Codeproject (кредит Nitron ):

Я думаю, що це той самий діалог, про який ви говорите - можливо, це допоможе, якщо ви додасте скріншот?

bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
    bool retVal = false;

    // The BROWSEINFO struct tells the shell how it should display the dialog.
    BROWSEINFO bi;
    memset(&bi, 0, sizeof(bi));

    bi.ulFlags   = BIF_USENEWUI;
    bi.hwndOwner = hOwner;
    bi.lpszTitle = szCaption;

    // must call this if using BIF_USENEWUI
    ::OleInitialize(NULL);

    // Show the dialog and get the itemIDList for the selected folder.
    LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);

    if(pIDL != NULL)
    {
        // Create a buffer to store the path, then get the path.
        char buffer[_MAX_PATH] = {'\0'};
        if(::SHGetPathFromIDList(pIDL, buffer) != 0)
        {
            // Set the string value.
            folderpath = buffer;
            retVal = true;
        }       

        // free the item id list
        CoTaskMemFree(pIDL);
    }

    ::OleUninitialize();

    return retVal;
}

images.google.com/… Робіть дослідження, коли невизначено. Я описав те, що хотів, і FolderBrowserDialog вже був дискваліфікований як відповідь.
OwenP

"Мені відомо про FolderBrowserDialog, але мені ніколи не подобалося це діалогове вікно. Він починається занадто малим і не дає мені можливості скористатися можливістю введення шляху." Виконайте кілька досліджень самостійно - ви можете набрати туди шлях. У всякому разі, я думаю, це трохи неоднозначне питання, тож удачі з ним.
demoncodemonkey

@demoncodemonkey: Ви не можете ввести частину шляху, а потім перейти до потрібної цілі. На сьогоднішній день не так зручно, як варіанти, які пропонує FileOpenDialog.
Треб

1

У Vista ви можете використовувати IFileDialog з набором опцій FOS_PICKFOLDERS. Це призведе до появи вікна, схожого на OpenFileDialog, де ви можете вибрати папки:

var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);

if (frm.Show(owner.Handle) == S_OK) {
    IShellItem shellItem;
    frm.GetResult(out shellItem);
    IntPtr pszString;
    shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
    this.Folder = Marshal.PtrToStringAuto(pszString);
}

Для старих Windows завжди можна вдатися до хитрощів, вибравши будь-який файл у папці.

Робочий приклад, який працює на .NET Framework 2.0 та новіших версіях, можна знайти тут .


1

Ви можете використовувати такий код

Фільтр порожній рядок. Ім'я файлу - AnyName, але не пусте

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

6
Я знаю, що це стара публікація, але заради тих, хто хоче це спробувати, вона насправді не працює, якщо каталог, який ви хочете відкрити, абсолютно не має дочірніх каталогів. Отже, якщо я хочу дозволити своєму користувачу переглядати папку та вибирати її та заповнювати шлях до папки в якомусь текстовому полі, користувач ніколи не може вибрати C: \ SomeParentDir, якщо існує каталог C: \ SomeParentDir \ SomeChildDir, тому що вибравши "Відкрити "просто приводить вас до дочірнього каталогу.
Джим

Приємна спроба .. але це призводить до жахливого інтерфейсу користувача, оскільки "AnyFile" в текстовому полі просто чекає, коли користувач перекриє його текст. Крім того, користувач також може вибрати файли - недостатньо добре. але приємно спробувати ..
GY


-1

Я знаю, що питання стосувалося конфігурації, OpenFileDialogале, побачивши, що Google привів мене сюди, я також можу зазначити, що якщо ви ТИЛЬКО шукаєте папки, вам слід використовувати FolderBrowserDialogЗамість цього, як відповіли на інше питання ТА нижче

Як вказати шлях за допомогою діалогового вікна відкритого файлу на vb.net?


Оманливий оман. 1) Це не єдиний вибір; 2) У більшості випадків це не гарний вибір; Але для цього потрібен найменший код, торгується більше витраченого часу кінцевим користувачем.
Meow Cat 2012
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.