Desarrollo una aplicación WPF4 y en mi aplicación necesito que el usuario seleccione una carpeta donde la aplicación almacenará algo (archivos, informes generados, etc.).
Mis requisitos:
Posibilidad de ver el árbol de carpetas estándar
Posibilidad de seleccionar una carpeta
WPF look & feel, este diálogo debe verse como parte de una aplicación moderna diseñada para Windows Vista / 7 y no para Windows 2000 o incluso Win9x.
Según entiendo, hasta 2010 (.Net 4.0) no habrá un diálogo de carpeta estándar, pero tal vez haya algunos cambios en la versión 4.0.
¿O todo lo que hay que hacer es usar el cuadro de diálogo WinForms de la vieja escuela? Si es la única forma de hacer lo que necesito, ¿cómo puedo acercarme más al estilo Vista / 7 y no a Win9x?
En algunos foros, vi la implementación de dichos diálogos, pero con viejos icons feos como Windows 95. Realmente no se ve bien.
Escribí sobre esto en mi blog hace mucho tiempo, el soporte de WPF para los diálogos de archivos comunes es realmente malo (o al menos estaba en 3.5 no revisé en la versión 4), pero es fácil evitarlo.
Debe agregar el manifiesto correcto a su aplicación, que le dará un estilo moderno de cuadros de mensajes y carpetas (WinForms FolderBrowserDialog) pero no WPF abrir / guardar diálogos, esto se describe en esas 3 publicaciones (si no le importa) acerca de la explicación y solo quiere que la solución vaya directamente al tercero):
Afortunadamente, los diálogos de abrir / guardar son envoltorios muy delgados alrededor de la API de Win32 que es fácil de llamar con los indicadores adecuados para obtener el estilo Vista / 7 (después de configurar el manifiesto)
El libro de cocina de Windows Presentation Foundation 4.5 de Pavel Yosifovich en la página 155 en la sección “Uso de los cuadros de diálogo comunes” dice:
“¿Qué pasa con la selección de carpetas (en lugar de archivos)? WPF OpenFileDialog no es compatible con eso. Una solución es utilizar la clase FolderBrowseDialog de Windows Forms. Otra buena solución es utilizar el paquete de códigos API de Windows descrito en breve”.
Descargué el API Code Pack del paquete de código API de Windows® para Microsoft® .NET Framework Paquete de código API de Windows: ¿Dónde está? , luego agregué referencias a Microsoft.WindowsAPICodePack.dll y Microsoft.WindowsAPICodePack.Shell.dll a mi proyecto de WPF 4.5.
Ejemplo:
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 }
Microsoft.Win32.OpenFileDialog es el cuadro de diálogo estándar que utiliza cualquier aplicación en Windows. Su usuario no se sorprenderá por su apariencia cuando use WPF en .NET 4.0
El diálogo fue alterado en Vista. WPF en .NET 3.0 y 3.5 todavía usaba el diálogo heredado, pero eso fue corregido en .NET 4.0. Solo puedo adivinar que comenzaste este hilo porque estás viendo ese viejo diálogo. Lo que probablemente significa que en realidad está ejecutando un progtwig que se dirige a 3.5. Sí, el contenedor de Winforms recibió la actualización y muestra la versión de Vista. Clase System.Windows.Forms.OpenFileDialog, deberá agregar una referencia a System.Windows.Forms.
MVVM + WinForms FolderBrowserDialog como comportamiento
public class FolderDialogBehavior : Behavior
Uso
Blogpost: http://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html
Agregue el Código API de Windows Pack-Shell a su proyecto
using Microsoft.WindowsAPICodePack.Dialogs; ... var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; CommonFileDialogResult result = dialog.ShowDialog();
Según la respuesta de Oyun, es mejor usar una propiedad de dependencia para FolderName. Esto permite (por ejemplo) enlazar a sub-propiedades, lo que no funciona en el original. Además, en mi versión ajustada, el cuadro de diálogo muestra la selección de la carpeta inicial.
Uso en XAML:
Código:
using System.Windows; using System.Windows.Forms; using System.Windows.Interactivity; using Button = System.Windows.Controls.Button; public class FolderDialogBehavior : Behavior
Si no quiere usar Windows Forms ni editar archivos manifiestos, se me ocurrió un truco muy simple usando el diálogo SaveAs de WPF para realmente seleccionar un directorio.
No se necesita una directiva de uso, ¡simplemente copie y pegue el código a continuación!
Debería ser muy fácil de usar y la mayoría de las personas nunca lo notarán.
La idea surge del hecho de que podemos cambiar el título de ese diálogo, ocultar archivos y trabajar con el nombre del archivo resultante con bastante facilidad.
Es un gran truco seguro, pero tal vez hará el trabajo bien para su uso …
En este ejemplo, tengo un objeto de cuadro de texto para contener la ruta resultante, pero puede eliminar las líneas relacionadas y usar un valor de retorno 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 truco son:
La mayoría de las personas no se darán cuenta de esto, aunque definitivamente preferiría usar una forma oficial de WPF si Microsoft les saca la cabeza fuera de sí, pero hasta que lo hagan, esa es mi solución temporal.
Solo ese diálogo es FileDialog . Es parte de WinForms, pero en realidad es la única envoltura del diálogo de archivo del sistema operativo estándar WinAPI. Y no creo que sea feo, en realidad es parte del sistema operativo, por lo que parece que se ejecuta el sistema operativo.
De otra manera, no hay nada para ayudarte. O necesita buscar la implementación de terceros, ya sea gratis (y no creo que haya ningún bien) o pagado.