Подтвердить что ты не робот

Найдите каталог в С#

Как я могу представить элемент управления пользователю, который позволяет ему/ей выбирать каталог?

Кажется, что нет каких-либо встроенных элементов управления .net?

4b9b3361

Ответ 2

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

Ответ 3

Примечание: нет гарантии, что этот код будет работать в будущих версиях .NET Framework. Использование частных внутренних инфраструктур .Net, как это делается через отражение, вероятно, не очень хорошо. Используйте промежуточное решение, упомянутое внизу, поскольку API Windows с меньшей вероятностью изменится.

Если вы ищете подборщик папок, который больше похож на диалоговое окно Windows 7, с возможностью копирования и вставки из текстового поля внизу и навигационной панели слева с избранными и обычными местами, вы можете получить доступ к ней очень легким способом.

Пользовательский интерфейс FolderBrowserDialog очень минимален:

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

Но вы можете использовать это вместо:

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

Здесь класс, который открывает сборщик папок в стиле Vista, используя интерфейс .Net private IFileDialog, без прямого использования взаимодействия в коде (.Net позаботится об этом для вас). Он возвращается к диалогу pre-Vista, если не в достаточно высокой версии Windows. Должен работать в Windows 7, 8, 9, 10 и выше (теоретически).

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

Я разработал это как очищенную версию . В диалоговом окне выбора папки NET Win 7 в стиле Билл Седдон из lyquidity.com (у меня нет аффилированности). Я написал свой собственный, потому что для его решения требуется дополнительный класс Reflection, который не нужен для этой целенаправленной цели, использует управление потоком на основе исключений, не кэширует результаты своих вызовов отражения. Обратите внимание, что вложенный статический класс VistaDialog таков, что его статические переменные отражения не пытаются заселяться, если метод Show никогда не вызывается.

Он используется в форме 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.

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

Ответ 4

Вы можете просто использовать класс FolderBrowserDialog из пространства имен System.Windows.Forms.

Ответ 5

Пожалуйста, не пытайтесь использовать свой собственный класс TreeView/DirectoryInfo. С одной стороны, есть много приятных функций, которые вы получаете бесплатно (значки/щелчок правой кнопкой мыши/сети) с помощью SHBrowseForFolder. Для другого есть кромки/уловы, которые вы, вероятно, не будете знать.

Ответ 6

Вы можете использовать TreeView в сочетании с классом DirectoryInfo.

Ответ 7

Для большей функциональности, чем FolderBrowserdialog, например фильтрация, флажки и т.д., посмотрите на сторонние элементы управления, такие как Shell MegaPack, Поскольку они являются элементами управления, поэтому их можно поместить в свои собственные формы, а не появляться в виде модального диалога.