Diálogo Abrir directorio


Quiero que el usuario seleccione un directorio donde se guardará un archivo que luego generaré. Sé que en WPF debería usar el OpenFileDialog de Win32, pero desafortunadamente el diálogo requiere que se seleccionen archivos - permanece abierto si simplemente hago clic en Aceptar sin elegir uno. Podría "hackear" la funcionalidad dejando que el usuario elija un archivo y luego quitar la ruta para averiguar a qué directorio pertenece, pero eso no es intuitivo en el mejor de los casos. ¿Alguien ha visto esto antes?

Author: H.B., 2009-12-17

13 answers

Puede usar la clase FolderBrowserDialog integrada para esto. No importa que esté en el espacio de nombres System.Windows.Forms.

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

Si desea que la ventana sea modal sobre alguna ventana WPF, vea la pregunta Cómo usar un FolderBrowserDialog desde una aplicación WPF.


EDIT: Si desea algo un poco más elegante que la sencilla y fea carpeta Windows Forms Browserdialog, hay algunas alternativas que le permiten usar el diálogo Vista lugar:

  • Bibliotecas de terceros, como Diálogos Ookii (. NET 3.5)
  • El Paquete de código API de Windows-Shell :

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

    Tenga en cuenta que este cuadro de diálogo no está disponible en sistemas operativos anteriores a Windows Vista, así que asegúrese de comprobar CommonFileDialog.IsPlatformSupported primero.

 350
Author: Heinzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-03 08:50:48

He creado un UserControl que se usa así:

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

La fuente xaml se ve así:

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

Y el código detrás

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();
            }
        }
    }
 }
 33
Author: adrianm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-17 15:04:05

Estoy usando Ookii dialogs por un tiempo y funciona bien para WPF.

Aquí está la página directa:

Http://www.ookii.org/Blog/new_download_ookiidialogs

 8
Author: Rafael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-10 12:12:06

Para el Diálogo de Directorio para obtener la Ruta del Directorio, Primero Agregue el Sistema de referencia.Windows.Formularios, y luego Resolver, y luego poner este código en un clic de botón.

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

(folderpathTB es el nombre del cuadro de texto donde wana puso la ruta de la carpeta, O u puede asignarla a una variable de cadena también, por ejemplo)

    string folder = dialog.SelectedPath;

Y si desea obtener el nombre de archivo / ruta, Simplemente haga esto en el botón Haga clic en

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

(folderpathTB es el nombre del cuadro de texto donde wana pongo la ruta del archivo, O u puede asignarlo a una variable de cadena también)

Nota: Para el Diálogo de carpeta, el Sistema.Windows.Forma.dll debe agregarse al proyecto, de lo contrario no funcionaría.

 6
Author: Zia Ur Rahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-07 05:20:51

Encontré el siguiente código en el siguiente enlace... y funcionó Diálogo Seleccionar carpeta 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
}
 5
Author: Saurabh Raoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:59

La mejor manera de lograr lo que quieres es crear tu propio control basado en wpf , o usar uno que fue hecho por otras personas
¿Por qué? porque habrá un impacto notable en el rendimiento al usar el diálogo winforms en una aplicación wpf (por alguna razón)
recomiendo este proyecto
https://opendialog.codeplex.com/
o Nuget:

PM> Install-Package OpenDialog

Es muy amigable con MVVM y no está envolviendo el diálogo winforms

 4
Author: bigworld12,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-12 17:47:37

El diálogo de la carpeta Ookii se puede encontrar en Nuget.

PM> Install-Package Ookii.Dialogs

Y, el código de ejemplo es el siguiente.

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
    textBoxFolderPath.Text = dialog.SelectedPath;
}
 4
Author: Youngjae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-06 03:21:50

El Ookii VistaFolderBrowserDialog es el que quieres.

Si solo desea el Navegador de carpetas desde Ooki Dialogs y nada más entonces descargue la fuente, elija los archivos que necesita para el navegador de carpetas (sugerencia: 7 archivos) y se construye bien en.NET 4.5.2. Tuve que añadir una referencia a System.Drawing. Compara las referencias del proyecto original con las tuyas.

¿Cómo averiguar qué archivos? Abra su aplicación y Ookii en diferentes instancias de Visual Studio. Añadir VistaFolderBrowserDialog.cs a tu app y sigue agregando archivos hasta que desaparezcan los errores de compilación. Encuentra las dependencias en el proyecto Ookii - Control-Haga clic en la que desea seguir de vuelta a su fuente (juego de palabras).

Aquí están los archivos que necesita si es demasiado perezoso para hacer eso ...

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

Edita la línea 197 en VistaFolderBrowserDialog.cs a menos que quieras incluir su Resources.Resx

lanzar nueva InvalidOperationException (Propiedades.Recurso.Pliegos de herramientas);

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

Añadir su aviso de derechos de autor para su aplicación según su license.txt

El código en la línea 160-169 de \Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs es un ejemplo que puede usar, pero tendrá que eliminar this, de MessageBox.Show(this, para WPF.

Funciona en Mi Máquina [TM]

 2
Author: CAD bloke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-27 13:28:05

Yo sugeriría, para agregar en el paquete nugget:

  Install-Package OpenDialog

Entonces la forma de usarlo es:

    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();

Aquí está la documentación: http://opendialog.codeplex.com/documentation

Funciona para archivos, archivos con filtro, carpetas, etc

 2
Author: Jose Ortega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-17 08:54:18

Sé que esta es una pregunta antigua, pero una forma sencilla de hacerlo es usar la opción FileDialog proporcionada por WPF y usar System. IO. Path. getDirectory (nombre de archivo).

 2
Author: Gregory Eaton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-13 21:31:10

Ninguna de estas respuestas funcionó para mí (generalmente faltaba una referencia o algo en ese sentido)

Pero esto simplemente lo hizo:

Usando FolderBrowserDialog en la aplicación WPF

Agregue una referencia a System.Windows.Forms y use este código:

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

No es necesario rastrear los paquetes que faltan. O añadir enormes clases

Esto me da un selector de carpetas moderno que también le permite crear una nueva carpeta

Todavía no veo el impacto cuando desplegado en otras máquinas

 1
Author: Nick.McDermaid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-18 07:26:30

Puedes usar smth así en WPF. He creado un método de ejemplo. Compruebe a continuación.

public string getFolderPath()
{
           // Create OpenFileDialog 
           Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

           OpenFileDialog openFileDialog = new OpenFileDialog();
           openFileDialog.Multiselect = false;

           openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
           if (openFileDialog.ShowDialog() == true)
           {
               System.IO.FileInfo fInfo = new System.IO.FileInfo(openFileDialog.FileName);
               return fInfo.DirectoryName;
           }
           return null;           
       }
 1
Author: koberone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-12 21:46:13

Para aquellos que no quieren crear un diálogo personalizado, pero aún prefieren una forma 100% WPF y no quieren usar DDLS separadas, dependencias adicionales o API obsoletas, se me ocurrió un truco muy simple usando el diálogo Guardar como.

No se necesita directiva de uso, simplemente puede copiar y pegar el código a continuación !

Todavía debe ser muy fácil de usar y la mayoría de la gente nunca se dará cuenta.

La idea viene del hecho de que podemos cambiar el título de ese diálogo, ocultar archivos, y trabajar alrededor del nombre de archivo resultante con bastante facilidad.

Es un gran truco seguro, pero tal vez va a hacer el trabajo muy bien para su uso...

En este ejemplo tengo un objeto textbox para contener la ruta resultante, pero puede eliminar las líneas relacionadas y usar un valor devuelto si lo desea...

// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
    string path = dialog.FileName;
    // Remove fake filename from resulting path
    path = path.Replace("\\select.this.directory", "");
    path = path.Replace(".this.directory", "");
    // If user has changed the filename, create the new directory
    if (!System.IO.Directory.Exists(path)) {
        System.IO.Directory.CreateDirectory(path);
    }
    // Our final value is in path
    textbox.Text = path;
}

Los únicos problemas con este hackeo son:

  • El botón de reconocimiento todavía dice "Guardar" en lugar de algo como "Seleccionar directorio", pero en un caso como minas "Guardar" el selección de directorio por lo que todavía funciona...
  • El campo de entrada todavía dice "Nombre de archivo" en lugar de "Nombre de directorio", pero podemos decir que un directorio es un tipo de archivo...
  • Todavía hay un menú desplegable "Guardar como tipo", pero su valor dice "Directorio (*.este.directorio)", y el usuario no puede cambiarlo por otra cosa, funciona para mí...

La mayoría de la gente no se dará cuenta de estos, aunque definitivamente preferiría usar una forma oficial de WPF si Microsoft sacara sus cabezas de sus culos, pero hasta que lo hagan, esa es mi solución temporal.

 1
Author: Olivier St-L,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-09 20:43:00