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

Я хочу, чтобы пользователь выбирал каталог, в котором будет сохранен файл, который я буду генерировать. Я знаю, что в WPF я должен использовать OpenFileDialog из Win32, но, к сожалению, для диалога требуется, чтобы файлы были выбраны - он остается открытым, если я просто нажимаю OK, не выбирая его. Я мог бы "взломать" функциональность, позволив пользователю выбрать файл, а затем разделив путь, чтобы выяснить, в каком каталоге он находится, но в лучшем случае это неинтуитивно. Кто-нибудь видел это раньше?

Ответ 1

Для этого вы можете использовать встроенный FolderBrowserDialog класс. Не обращайте внимания на это в пространстве имен System.Windows.Forms.

using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
    System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}

Если вы хотите, чтобы окно было модальным над некоторым окном WPF, см. вопрос Как использовать FolderBrowserDialog из приложения WPF.


РЕДАКТИРОВАТЬ: Если вам нужно что-то более необычное, чем обычное, уродливое Windows Forms FolderBrowserDialog, есть несколько альтернатив, которые позволяют вместо этого использовать диалоговое окно Vista:

  • Сторонние библиотеки, такие как Диалоги Ookii (.NET 3.5)
  • Windows Code Code Pack-Shell:

    using Microsoft.WindowsAPICodePack.Dialogs;
    
    ...
    
    var dialog = new CommonOpenFileDialog();
    dialog.IsFolderPicker = true;
    CommonFileDialogResult result = dialog.ShowDialog();
    

    Обратите внимание, что это диалоговое окно недоступно в операционных системах старше Windows Vista, поэтому сначала проверьте CommonFileDialog.IsPlatformSupported.

Ответ 2

Я создал UserControl, который используется следующим образом:

  <UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>

Источник xaml выглядит следующим образом:

<UserControl x:Class="Utilities.WPF.FolderEntry"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DockPanel>
        <Button Margin="0" Padding="0" DockPanel.Dock="Right" Width="Auto" Click="BrowseFolder">...</Button>
        <TextBox Height="Auto" HorizontalAlignment="Stretch" DockPanel.Dock="Right" 
           Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </DockPanel>
</UserControl>

и код

public partial class FolderEntry {
    public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FolderEntry), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(FolderEntry), new PropertyMetadata(null));

    public string Text { get { return GetValue(TextProperty) as string; } set { SetValue(TextProperty, value); }}

    public string Description { get { return GetValue(DescriptionProperty) as string; } set { SetValue(DescriptionProperty, value); } }

    public FolderEntry() { InitializeComponent(); }

    private void BrowseFolder(object sender, RoutedEventArgs e) {
        using (FolderBrowserDialog dlg = new FolderBrowserDialog()) {
            dlg.Description = Description;
            dlg.SelectedPath = Text;
            dlg.ShowNewFolderButton = true;
            DialogResult result = dlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK) {
                Text = dlg.SelectedPath;
                BindingExpression be = GetBindingExpression(TextProperty);
                if (be != null)
                    be.UpdateSource();
            }
        }
    }
 }

Ответ 4

В диалоговом окне "Справочник", чтобы получить путь к каталогу, сначала добавьте ссылку System.Windows.Forms, а затем "Разрешить", а затем поместите этот код нажатием кнопки.

    var dialog = new FolderBrowserDialog();
    dialog.ShowDialog();
    folderpathTB.Text = dialog.SelectedPath;

(folderpathTB - это имя TextBox, где я wana помещаю путь к папке, или вы также можете назначить его строковой переменной i.e.)

    string folder = dialog.SelectedPath;

И если вы wana получаете FileName/path, просто сделайте это на кнопке Click

    FileDialog fileDialog = new OpenFileDialog();
    fileDialog.ShowDialog();
    folderpathTB.Text = fileDialog.FileName;

(folderpathTB - это имя TextBox, где я wana помещаю путь к файлу, или вы также можете назначить его строковой переменной)

Примечание. В диалоговом окне "Папка" в проект необходимо добавить файл System.Windows.Forms.dll, иначе он не будет работать.

Ответ 5

Я нашел ниже код ниже ссылки... и он работал Выберите диалог папки WPF

using Microsoft.WindowsAPICodePack.Dialogs;

var dlg = new CommonOpenFileDialog();
dlg.Title = "My Title";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = currentDirectory;

dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = currentDirectory;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;

if (dlg.ShowDialog() == CommonFileDialogResult.Ok) 
{
  var folder = dlg.FileName;
  // Do something with selected folder string
}

Ответ 6

Лучший способ добиться того, что вы хотите, - создать свой собственный элемент управления на основе wpf или использовать тот, который был сделан другими людьми
Зачем? потому что будет заметно влияние производительности при использовании диалога winforms в приложении wpf (по какой-то причине)
я рекомендую этот проект
 https://opendialog.codeplex.com/
или Nuget:

PM> Install-Package OpenDialog

он очень дружелюбен MVVM, и он не искажает диалог winforms

Ответ 7

Диалоговое окно папки Ookii можно найти в Nuget.

PM> Install-Package Ookii.Dialogs

И, пример кода выглядит следующим образом.

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
    textBoxFolderPath.Text = dialog.SelectedPath;
}

Ответ 8

Ookii VistaFolderBrowserDialog - тот, который вы хотите.

Если вы хотите, чтобы Браузер папок был Ooki Dialogs, и больше ничего загрузите Source, вишни выберите файлы, которые вам нужны для браузера папки (подсказка: 7 файлов), и он отлично работает в .NET 4.5.2. Мне пришлось добавить ссылку на System.Drawing. Сравните ссылки в исходном проекте с вашим.

Как вы определяете, какие файлы? Откройте приложение и Ookii в разных экземплярах Visual Studio. Добавьте VistaFolderBrowserDialog.cs в приложение и продолжайте добавлять файлы до тех пор, пока ошибки сборки не исчезнут. Вы находите зависимости в проекте Ookii - Control - щелкните тот, который вы хотите вернуть назад к своему источнику (каламбур).

Вот вам нужные файлы, если вы слишком ленивы, чтобы сделать это...

NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
   COMGuids.cs
   ErrorHelper.cs
   ShellComInterfaces.cs
   ShellWrapperDefinitions.cs

Измените строку 197 в VistaFolderBrowserDialog.cs, если вы не хотите включать их Resources.Resx

добавить новое InvalidOperationException (Properties.Resources.FolderBrowserDialogNoRootFolder);

throw new InvalidOperationException("Unable to retrieve the root folder.");

Добавьте свое уведомление об авторских правах в свое приложение в соответствии с их license.txt

Код в строке \Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs строка 160-169 - это пример, который вы можете использовать, но вам нужно удалить this, из MessageBox.Show(this, для WPF.

Работает на моей машине [TM]

Ответ 9

Я бы предложил добавить в пакет самородок:

  Install-Package OpenDialog

Тогда способ его использования:

    Gat.Controls.OpenDialogView openDialog = new Gat.Controls.OpenDialogView();
    Gat.Controls.OpenDialogViewModel vm = (Gat.Controls.OpenDialogViewModel)openDialog.DataContext;
    vm.IsDirectoryChooser = true;
    vm.Show();

    WPFLabel.Text = vm.SelectedFilePath.ToString();

Здесь документация: http://opendialog.codeplex.com/documentation

Работает для файлов, файлов с фильтром, папок и т.д.

Ответ 10

Я знаю, что это старый вопрос, но простой способ сделать это - использовать параметр FileDialog, предоставляемый WPF, и использовать System.IO.Path.GetDirectory(имя файла).

Ответ 11

Ни один из этих ответов не работал у меня (как правило, отсутствовала ссылка или что-то в этом роде)

Но это довольно просто:

Использование FolderBrowserDialog в приложении WPF

Добавьте ссылку на System.Windows.Forms и используйте этот код:

  var dialog = new System.Windows.Forms.FolderBrowserDialog();
  System.Windows.Forms.DialogResult result = dialog.ShowDialog();

Не нужно отслеживать недостающие пакеты. Или добавьте огромные классы

Это дает мне современный селектор папок, который также позволяет вам создать новую папку

Я пока не вижу влияния при развертывании на другие машины