Wpf окно выбора файла

Обновлено: 07.07.2024

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

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

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

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

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

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

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

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

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

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

Для WPF вы можете найти стандартные диалоговые окна как для сохранения, так и для открытия файлов в пространстве имен Microsoft.Win32. В этой статье мы рассмотрим класс OpenFileDialog, который позволяет легко отображать окно для открытия одного/нескольких файлов.

Простой пример использования OpenFileDialog

Давайте начнем использование OpenFileDialog без дополнительных опций, с помощью TextBox:


При нажатии на кнопку Open, отображается окно OpenFileDialog. В зависимости от Вашей версии Windows, Вы увидите нечто подобное:


Метод ShowDialog() возвращает логическое nullable значение (может быть true, false либо null). Если пользователь выберет файл и нажмет "Open" результатом будет True, и в этом случае мы попытаемся загрузить файл в элемент TextBox. Мы получили полный путь к выбранному файлу с помощью свойства FileName в OpenFileDialog.

Фильтрование

Обычно, при выборе файла, пользователь желает ограничить выбор одним или несколькими типами файлов. Например, Word в основном открывает файлы Word (с расширением .doc или .docx), а Блокнот - текстовые файлы (.txt).

Вы можете определить фильтр для диалоговоко окна OpenFileDialog с возможностью выбора ипользователем типов файлов и ограничения файлов, для большей наглядности. Это осуществляется с помощью свойства Filter, которое мы добавим к предыдущему примеру (после инициализации окна):


Заметьте, что теперь окно имеет выпадающий список с возможными для выбора типами файлов, все файлы отображаются в соответствии с выбранным расширением.

На первый взгляд, формат определения фильтра может показаться слегка странным, но в нем представлена удобочитаемая версия для пользователя и другая, для компьютера, который будет в состоянии их "прочитать" и разделить с помощью символа-сепаратора "|". Если Вы хотите определить больше чем один тип (как было в примере), просто добавьте необходимые Вам, с помощью выше введенного сепаратора.

Подводя итог, следующий код означает, что мы присваиваем типу название "Text files (*.txt)" (расширение в скобках - это знак внимания пользователю, он будет знать, какие типы включены в "Text files"), а вторая часть определяет, что будут показаны файлы с расширением .txt:

Конечно же, каждый создаваемый тип может иметь множество расширений. Например, изображения могут быть определены как для JPEG, так и для PNG файлов, вот так:

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

Определение каталога по умолчанию

Первоначальный каталог используемый классом OpenFileDialog уже определен в Windows, но используя свойство InitialDirectory, его можно переопределить. Обычно, Вы будете определять это значение специально для пользователя, всего приложения или, возможно, как каталог, который был использован с последний раз. Вы можете его определить как путь в формате строки, вот так:

В этом случае, я использовал путь к папке "Мои Документы", но обратите внимание на перечисление SpecialFolder - оно содержит множество интересных путей. Если хотите изучить полный список SpecialFolder, воспользуйтесь этой статьей MSDN.

Несколько файлов

Если Ваше приложение должно поддерживать открытие нескольких файлов или Вы просто хотите понять, как использовать OpenFileDialog для одновременного открытия нескольких файлов, просто включите свойство Multiselect. В следующем примере, мы это с успехом проделали, и, наш дорогой Читатель, собрали в одном все механизмы, рассмотренные в текущей главе (фильтрация, определение каталога по умолчанию):


Если Вы протестируете этот код, то заметите, что выбирать несколько файлов в одном каталоге становится возможным путем удерживания Ctrl или Shift и нажатием мыши. Выбрав их механизм в этом примере просто добавит файлы в элемент ListBox, в цикле по свойству FileNames.

В итоге

Наверняка Вы обратили внимание на то, что использование OpenFileDialog в WPF является очень простым, к тому же, данный механизм делает большую часть работы за Вас. Но заметьте, что в данном примере, для экономии места в коде, я не посвятил ни одной строки обработке исключений. При работе с файлами, и в целом при работе с входом-выходом, Вам всегда следует опасаться исключений, так как они легко могут появиться при работе с заблокированным файлом, несуществующим путем или другими.

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

отображения определенных сведений для пользователей;

сбора сведений от пользователей;

сбора и отображения сведений.

Эти типы окон называются диалоговыми окнами, и существует два типа: модальные и немодальные.

Модальное диалоговое окно отображается функцией, когда для продолжения работы функции требуются дополнительные данные от пользователя. Поскольку функция зависит от модального диалогового окна для сбора данных, это окно также не разрешает пользователю активизировать другие окна в приложении, пока остается открытым. В большинстве случаев модальное диалоговое окно позволяет пользователю подать сигнал о завершении работы с модальным диалоговым окном, нажав кнопку ОК или Отмена . Нажатие кнопки ОК означает, что пользователь вводит данные и желает, чтобы функция продолжала обрабатывать эти данные. Нажатие кнопки Отмена означает, что пользователь хочет остановить выполнение функции. Наиболее распространенными примерами модальных диалоговых окон являются окна, которые отображаются для открытия, сохранения и печати данных.

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

Диалоговое окно «текстовый процессор» с вопросом, нужно ли сохранить изменения в документе перед закрытием приложения.

Хотя MessageBox может предложить простое взаимодействие с пользователем диалогового окна, преимущество использования MessageBox — это единственный тип окна, который может быть отображен приложениями, выполняемыми в песочнице безопасности частичного доверия (см. раздел Безопасность), например в приложениях браузера XAML (XBAP).

Общие диалоговые окна

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

Windows Presentation Foundation (WPF) инкапсулирует общие диалоговые окна открытия файла, сохранения файлов и печати и предоставляет их в качестве управляемых классов для использования в автономных приложениях. В этом разделе приводится краткий обзор каждого типа диалоговых окон.

Диалоговое окно открытия файла

Диалоговое окно открытия файлов, показанное на следующем рисунке, используется функциональностью открытия файла для получения имени открываемого файла.

Открытие диалогового окна, показывающего расположение для извлечения файла.

Общее диалоговое окно открытия файла реализуется как OpenFileDialog класс и находится в Microsoft.Win32 пространстве имен. Следующий код показывает, как создавать, настраивать и отображать такое окно, а также как обрабатывать результат.

Дополнительные сведения о диалоговом окне Открытие файла см. в разделе Microsoft.Win32.OpenFileDialog .

OpenFileDialog может использоваться для безопасного извлечения имен файлов приложениями, работающими с частичным доверием (см. раздел Безопасность).

диалоговое окно сохранения файлов

Диалоговое окно сохранения файлов, показанное на следующем рисунке, используется функциональностью сохранения файла для получения имени сохраняемого файла.

Диалоговое окно Сохранить как, в котором отображается расположение для сохранения файла.

Диалоговое окно «Общие файлы сохранения» реализуется как SaveFileDialog класс и находится в Microsoft.Win32 пространстве имен. Следующий код показывает, как создавать, настраивать и отображать такое окно, а также как обрабатывать результат.

Дополнительные сведения о диалоговом окне Сохранение файла см. в разделе Microsoft.Win32.SaveFileDialog .

Печать - диалоговое окно

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

Снимок экрана, на котором показано диалоговое окно "Печать".

Общее диалоговое окно печати реализуется как PrintDialog класс и находится в System.Windows.Controls пространстве имен. Следующий код показывает, как создавать, настраивать и отображать такое окно.

Дополнительные сведения о диалоговом окне Печать см. в разделе System.Windows.Controls.PrintDialog . Подробное описание печати в WPF см. в разделе Общие сведения о печати.

Настраиваемые диалоговые окна

Хотя общие диалоговые окна полезны и должны использоваться, когда это возможно, они не поддерживают требований диалоговых окон отдельного домена. В этих случаях необходимо создавать собственные диалоговые окна. Как мы увидим, диалоговое окно является окном со специальным поведением. Window реализует эти поведения и, следовательно, используется Window для создания настраиваемых модальных и немодальных диалоговых окон.

Создание модального настраиваемого диалогового окна

В этом разделе показано, как использовать Window для создания типичной реализации модального диалогового окна с помощью Margins диалогового окна в качестве примера (см. Пример диалогового окна). Это Margins диалоговое окно показано на следующем рисунке.

Диалоговое окно «поля» с полями для определения левого поля, верхнего поля, правого поля и нижнего поля.

Настройка модального диалогового окна

Пользовательский интерфейс для типичного диалогового окна включает следующее.

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

Кнопка ОК , которую пользователь нажимаем, чтобы закрыть диалоговое окно, вернуться к функции и продолжить обработку.

Кнопка "Отмена" , которую пользователь нажмет для закрытия диалогового окна и прекращения дальнейшей обработки функции.

Кнопка Закрыть в заголовке окна.

Кнопки сворачивания, развертывания и восстановления .

Системное меню для сворачивания, развертывания, восстановления и закрытия диалогового окна.

Расположение выше и в центре окна, открывшего диалоговое окно.

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

Клавиша ESC в качестве сочетания клавиш, которое вызывает нажатие кнопки Отмена . Это можно сделать, задав IsCancel для свойства кнопки Отмена значение true .

Клавиша ВВОД (или возврата) в качестве сочетания клавиш, которое вызывает нажатие кнопки ОК . Для этого нужно задать IsDefault свойство кнопки ОК true .

Следующий код демонстрирует такую конфигурацию.

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

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

Открытие модального диалогового окна

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

Здесь код передает в диалоговое окно сведения по умолчанию (текущие поля). Он также задает Window.Owner свойство со ссылкой на окно, в котором отображается диалоговое окно. в общем случае необходимо всегда задавать владельца для диалогового окна, чтобы обеспечить поведение окна, которое является общим для всех диалоговых окон (дополнительные сведения см. в разделе обзор Windows WPF ).

Необходимо указать владельца для поддержки автоматизации ПОЛЬЗОВАТЕЛЬСКОГО интерфейса для диалоговых окон (см. Обзор модели автоматизации пользовательскогоинтерфейса).

После настройки диалогового окна он отображается как модальный путем вызова ShowDialog метода.

Проверка предоставленных пользователем данных

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

С точки зрения безопасности следует проверять все входные данные.

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

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

С точки зрения производительности проверка данных в многоуровневом приложении может уменьшить количество циклов обработки между уровнями клиента и приложения, особенно в том случае, если в приложение входят веб-службы или серверные базы данных.

Чтобы проверить привязанный элемент управления в WPF, необходимо определить правило проверки и связать его с привязкой. Правило проверки является пользовательским классом, производным от ValidationRule . В следующем примере показано правило проверки, MarginValidationRule которое проверяет, что привязанное значение — Double и находится в указанном диапазоне.

В этом коде логика проверки правила проверки реализуется путем переопределения Validate метода, который проверяет данные и возвращает соответствующее значение ValidationResult .

Чтобы сопоставить это правило проверки со связанным элементом управления, используется следующая разметка.

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

Диалоговое окно полей с красной границей вокруг недействительного значения левого поля.

WPF не ограничивает доступ пользователя к недопустимому элементу управления до тех пор, пока не будут введены допустимые данные. Это правильное поведение диалогового окна; пользователь должен иметь возможность свободно перемещаться по элементам управления в диалоговом окне, независимо от того, правильны ли введенные данные. Однако это означает, что пользователь может ввести недопустимые данные и нажать кнопку ОК . По этой причине код также должен проверять все элементы управления в диалоговом окне, когда нажата кнопка ОК , обрабатывая Click событие.

Этот код перечисляет все объекты зависимостей в окне и, если они являются недопустимыми (возвращенные GetHasError , недопустимый элемент управления получает фокус, IsValid метод возвращает false , а окно считается недопустимым.

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

Установка результата модального диалогового окна

Открытие диалогового окна с помощью ShowDialog является фундаментальным методом, аналогичным вызову метода: код, открывший диалоговое окно с использованием ShowDialog Waits до ShowDialog возврата. При ShowDialog возврате код, вызвавший его, должен решить, следует ли продолжать обработку или прекратить обработку в зависимости от того, нажал ли пользователь кнопку ОК или кнопку Отмена . Чтобы упростить это решение, диалоговое окно должно вернуть выбор пользователя в качестве Boolean значения, возвращаемого ShowDialog методом.

При нажатии кнопки ОК ShowDialog должен возвращаться true . Это достигается путем задания DialogResult Свойства диалогового окна при нажатии кнопки ОК .

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

При нажатии кнопки Отмена ShowDialog должна возвращаться false , что также требует установки DialogResult Свойства.

Если IsCancel свойство кнопки имеет значение true и пользователь нажимает кнопку « Отмена » или клавишу ESC, автоматически устанавливается значение DialogResult false . Следующая разметка действует аналогично предыдущему коду без необходимости в обработке Click события.

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

Обработка данных, возвращаемых из модального диалогового окна

Если параметр DialogResult задается в диалоговом окне, то функция, которая открыла ее, может получить результат диалогового окна, проверив DialogResult свойство при ShowDialog возврате.

Если диалоговое окно имеет значение true , функция использует его в качестве подсказки для получения и обработки данных, предоставленных пользователем.

После ShowDialog возврата диалоговое окно нельзя открыть повторно. Вместо этого придется создать новый экземпляр.

Если результат диалога равен false , функция должна завершить обработку соответствующим образом.

Создание немодального настраиваемого диалогового окна

Немодальное диалоговое окно, например диалоговое окно поиска, показанное на следующем рисунке, в основном имеет такой же внешний вид, как и модальное диалоговое окно.

Снимок экрана, на котором отображается диалоговое окно "найти".

Однако поведение несколько отличается, как показано в следующих разделах.

Открытие немодального диалогового окна

Немодальное диалоговое окно открывается путем вызова Show метода.

В отличие от ShowDialog , функция Show возвращает значение немедленно. Следовательно, вызывающее окно не может определить, когда немодальное диалоговое окно закрывается, и поэтому не знает, когда следует проверить результат диалогового окна или получить данные из диалогового окна для дальнейшей обработки. Поэтому диалоговому окну необходимо создать альтернативный способ возврата данных в вызывающее окно для обработки.

Обработка данных, возвращенных из немодального диалогового окна

В этом примере объект FindDialogBox может вернуть один или несколько результатов поиска в главное окно в зависимости от искомого текста без какой бы то ни было определенной частоты. Как и в случае с модальным диалоговым окном, немодальное диалоговое окно может возвращать результаты с помощью свойств. Однако окну, которому принадлежит данное диалоговое окно, нужно знать, когда следует проверять эти свойства. Один из способов сделать это — реализовать для диалогового окна событие, которое возникает всякий раз, когда текст найден. FindDialogBox реализует TextFoundEvent для этой цели, для которой сначала требуется делегат.

С помощью TextFoundEventHandler делегата FindDialogBox реализует TextFoundEvent .

Следовательно, Find может вызвать событие при обнаружении результата поиска.

Затем окну-владельцу нужно зарегистрировать и обработать это событие.

Закрытие немодального диалогового окна

Поскольку DialogResult не нужно задавать, немодальное диалоговое окно можно закрыть с помощью механизмов, предоставляемых системой, включая следующие:

Нажатие кнопки Закрыть в строке заголовка.

Нажатие клавиш ALT+F4.

В меню система выберите пункт Закрыть .

Кроме того, код может вызывать Close при нажатии кнопки Закрыть .

Часто при отображении окна как модального пользователю предлагается сделать какой-нибудь выбор. Код, отображающий окно, дожидается получения результата этого выбора и затем выполняет на его основании соответствующее действие. Такое проектное решение называется моделью диалогового окна, а само отображаемое модальное окно — диалоговым окном.

Этот шаблон проектирования легко корректировать за счет создания в диалоговом окне общедоступного свойства. Такое свойство может устанавливаться, когда пользователь сделал выбор в диалоговом окне. Далее диалоговое окно может закрываться, а отображавший его код — проверять установленное для свойства значение и на его основе определять, какое действие должно быть выполнено следующим. (Имейте в виду, что даже когда окно закрывается, объект окна и информация обо всех его элементах управления все равно существует до тех пор, пока ссылающаяся на него переменная не покинет область действия.)

К счастью, такая инфраструктура уже отчасти жестко закодирована в классе Window. У каждого окна имеется уже готовое свойство DialogResult, которое может принимать значение true, false или null. Обычно значение true означает, что пользователь выбрал продолжение операции (например, щелкнул на кнопке ОК), а значение false — что он отменил операцию.

Лучше всего, когда результаты диалогового окна возвращаются в вызывающий код в виде значения, возвращаемого методом ShowDialog(). Это позволяет создавать, отображать и анализировать результаты диалогового окна с помощью простого кода:

Использование свойства DialogResult не исключает возможности добавления в окно специальных свойств. Например, исключительно целесообразно использовать свойство DialogResult для информирования вызывающего кода о том, разрешено или отменено было действие, и для предоставления других важных деталей через специальные свойства. В случае обнаружения в свойстве DialogResult значения true вызывающий код далее может проверять эти другие свойства для извлечения необходимой ему информации.

Также существует один сокращенный путь. Вместо того чтобы устанавливать свойство DialogResult вручную после выполнения пользователем щелчка на кнопке, можно назначить кнопку принятия (установкой для свойства IsDefault значения true). Тогда щелчок на этой кнопке будет автоматически приводить к установке свойства DialogResult в true. Подобным образом также можно предусмотреть кнопку отмены (за счет установки значения true для свойства IsCancel), в результате чего щелчок на ней будет автоматически приводить к установке свойства DialogResult в Cancel.

Модель диалогового окна в WPF отличается от той, что предлагается в Windows Forms. Там кнопки не предоставляют свойства DialogResult, из-за чего создавать можно только кнопки по умолчанию и кнопки отмены. Свойство DialogResult может принимать только значения true, false и null (последнее устанавливается для него изначально). Вдобавок щелчок на кнопке не приводит к автоматическому закрытию окна — код, выполняющий эту операцию, необходимо писать отдельно.

Общие диалоговые окна

Операционная система Windows включает много встроенных диалоговых окон, доступ к которым можно получать через API-интерфейс Windows. Для некоторых из них WPF предоставляет классы-оболочки.

Существует веская причина того, что WPF не включает упаковщики для абсолютно всех API-интерфейсов Windows. Одной из задач WPF является отделение от Windows API для получения возможности использования в других средах (например, в браузере) или переноса на другие платформы. Также многие из встроенных диалоговых окон уже начинают устаревать и потому не должны применяться в современных приложениях. Вдобавок в версии Windows 7 предпочтение уже отдается использованию не диалоговых окон, а основанных на задачах панелей и навигации.

Для класса MessageBox в WPF предусмотрена специальная поддержка функций печати, подразумевающих использование класса PrintDialog, а также классов OpenFileDialog и SaveFileDialog в пространстве имен Microsoft.Win32.

Классы OpenFileDialog и SaveFileDialog получают дополнительные функциональные средства (часть из которых наследуются от класса FileDialog). Оба из них поддерживают строку фильтра, которая устанавливает разрешенные расширения файлов. Класс OpenFileDialog также предлагает свойства, которые позволяют проверять выбор пользователя (CheckFileExists) и предоставлять ему возможность выбирать сразу несколько файлов (Multiselect). Ниже показан пример кода, который отображает диалоговое окно OpenFileDialog и выбранные файлы в окне списка после закрытия этого диалогового окна:

В предыдущих версиях WPF классы диалоговых окон всегда отображали диалоговые окна в старом стиле Windows ХР. В WPF 4 они были обновлены и оснащены поддержкой Windows Vista и Windows 7. Это означает то, что при запуске приложения под управлением более новой версии Windows диалоговые окна будут автоматически отображаться в современном стиле.

Я разрабатываю приложение WPF4, и в моем приложении мне нужно позволить пользователю выбрать папку, в которой приложение будет хранить что-то (файлы, сгенерированные отчеты и т. д.).

возможность видеть стандартное дерево папок

возможность выбора папки

WPF look & feel, этот диалог должен выглядеть как часть современного приложения, предназначенного для Windows Vista / 7, а не Windows 2000 или даже в Win9x.

или все, что нужно сделать, это использовать диалог WinForms старой школы? Если это единственный способ сделать то, что мне нужно, как я могу сделать его ближе к стилю Vista/7, а не Win9x?

на некоторых форумах я видел реализацию таких диалогов, но со старыми уродливыми значками à la Windows 95. Это действительно не выглядит милый.

Я писал об этом в своем блоге давным - давно, поддержка WPF для общих диалоговых окон файлов действительно плоха (или, по крайней мере, была в 3.5, я не проверял версию 4), но это легко обойти.

к счастью, диалоги открытия / сохранения очень тонкие обертки вокруг Win32 API, который легко вызвать с правильными флагами, чтобы получить стиль Vista / 7 (после установки манифеста)

Windows Presentation Foundation 4.5 Поваренная Книга по Yosifovich Павел на стр. 155 в разделе "использование стандартных диалоговых окон" говорит:

" Как насчет выбора папки (вместо файлов)? В WPF OpenFileDialog не поддерживает это. Одним из решений является использование Windows Класс FolderBrowseDialog форм. Другим хорошим решением является использование Пакет кода API Windows описан вкратце."

MVVM + WinForms FolderBrowserDialog как поведение

основываясь на ответе Oyun, лучше использовать свойство зависимостей для имени папки. Это позволяет (например) привязку к вложенным свойствам, которые не работают в оригинале. Кроме того, в моей скорректированной версии диалоговое окно показывает выбор начальной папки.

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

Если вы не хотите использовать Windows Forms или редактировать файлы манифеста, я придумал очень простой хак, используя диалоговое окно SaveAs WPF для фактического выбора каталога.

нет необходимости использовать директиву, вы можете просто скопировать-вставить код ниже !

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

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

это большой Хак наверняка, но, возможно, он будет делать работу просто отлично для вашего использования.

в этом примере у меня есть объект textbox, содержащий результирующий путь, но вы можете удалить связанные строки и использовать возвращаемое значение, если хотите.

единственные проблемы с этим Хак:

  • кнопка подтверждения по-прежнему говорит "сохранить" вместо чего-то вроде "выбрать каталог", но в таком случае, как шахты, я "сохраняю" каталог так он все еще работает.
  • поле ввода по-прежнему говорит "Имя файла" вместо "имя каталога", но мы можем сказать, что каталог является типом файла.
  • по-прежнему есть раскрывающийся список" Сохранить как тип", но его значение говорит " каталог (*.этот.каталог)", и пользователь не может изменить его на что-то другое, у меня работает.

большинство людей не заметят их, хотя я определенно предпочел бы использовать официальный способ WPF, если microsoft получит их головы из задниц, но пока они этого не сделают, это мое временное решение.

на диалоги Ookii для WPF есть VistaFolderBrowserDialog класс, который обеспечивает полную реализацию диалогового окна браузера папок для WPF.

enter image description here

существует также версия, которая работает с Windows Forms.

только такой диалог классов filedialog. Его часть WinForms,но его фактически только обертка вокруг стандартного диалогового окна ОС WinAPI. И я не думаю, что это уродливо, на самом деле это часть ОС, поэтому она выглядит как ОС, на которой она работает.

другой способ, нет ничего, чтобы помочь вам. Вам либо нужно искать стороннюю реализацию, либо бесплатную (и я не думаю, что есть что-то хорошее), либо платную.

Читайте также: