Je veux que l'utilisateur sélectionne un répertoire dans lequel un fichier que je générerai ensuite sera sauvegardé. Je sais que dans WPF, je devrais utiliser la variable OpenFileDialog
de Win32, mais malheureusement, la boîte de dialogue nécessite la sélection d'un fichier (s). Elle reste ouverte si je clique simplement sur OK sans en choisir un. Je pourrais "pirater" la fonctionnalité en laissant l’utilisateur choisir un fichier, puis en masquer le chemin pour déterminer le répertoire auquel il appartient, mais cela n’est pas tout à fait intuitif. Quelqu'un a-t-il déjà vu cela auparavant?
Vous pouvez utiliser la classe FolderBrowserDialog class intégrée pour cela. Ne vous inquiétez pas que cela se trouve dans l'espace de noms System.Windows.Forms
.
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}
Si vous souhaitez que la fenêtre soit modale sur une fenêtre WPF, consultez la question Comment utiliser un FolderBrowserDialog à partir d’une application WPF .
EDIT: Si vous voulez quelque chose d'un peu plus sophistiqué que le simple, dépliant Windows Forms FolderBrowserDialog, certaines alternatives vous permettent d'utiliser la boîte de dialogue Vista à la place:
Le Windows API Code Pack-Shell :
using Microsoft.WindowsAPICodePack.Dialogs;
...
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
Notez que cette boîte de dialogue n'est pas disponible sur les systèmes d'exploitation antérieurs à Windows Vista. Vérifiez donc d'abord CommonFileDialog.IsPlatformSupported
.
J'ai créé un UserControl qui est utilisé comme ceci:
<UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>
La source xaml ressemble à ceci:
<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>
et le code-behind
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();
}
}
}
}
J'utilise dialogues Ookii pendant un moment et ça marche bien pour WPF.
Voici la page directe:
Pour que la boîte de dialogue Répertoire obtienne le chemin du répertoire, ajoutez d’abord la référence System.Windows.Forms, puis cliquez sur Résoudre, puis placez ce code en un clic de bouton.
var dialog = new FolderBrowserDialog();
dialog.ShowDialog();
folderpathTB.Text = dialog.SelectedPath;
(folderpathTB est le nom de la zone de texte dans laquelle je mets le chemin du dossier, OR u peut l’affecter à une variable chaîne aussi).
string folder = dialog.SelectedPath;
Et si vous voulez obtenir FileName/path, faites-le simplement en cliquant sur le bouton
FileDialog fileDialog = new OpenFileDialog();
fileDialog.ShowDialog();
folderpathTB.Text = fileDialog.FileName;
(folderpathTB est le nom de la zone de texte dans laquelle je mets le chemin du fichier, OR u peut également l'affecter à une variable de chaîne)
Remarque: Pour la boîte de dialogue Dossier, la System.Windows.Forms.dll doit être ajoutée au projet, sinon cela ne fonctionnerait pas.
La boîte de dialogue du dossier Ookii est disponible sur Nuget.
PM> Install-Package Ookii.Dialogs
Et, exemple de code est comme ci-dessous.
var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
textBoxFolderPath.Text = dialog.SelectedPath;
}
Le meilleur moyen d’atteindre ce que vous voulez est de créer votre propre contrôle basé sur wpf ou d’utiliser un contrôle créé par d’autres personnes.
Pourquoi ? parce que l'utilisation de la boîte de dialogue winforms dans une application wpf aura un impact notable sur les performances (pour une raison quelconque)
je recommande ce projet
https://opendialog.codeplex.com/
ou Nuget:
PM> Install-Package OpenDialog
il est très convivial avec MVVM et n'emballe pas le dialogue de winforms
Pour ceux qui ne veulent pas créer une boîte de dialogue personnalisée mais préfèrent tout de même une méthode 100% WPF et ne veulent pas utiliser de DDL séparés, de dépendances supplémentaires ou d'API obsolètes, j'ai conçu un hack très simple à l'aide de la boîte de dialogue Enregistrer sous.
Aucune directive d'utilisation nécessaire, vous pouvez simplement copier-coller le code ci-dessous!
Il devrait toujours être très convivial et la plupart des gens ne le remarqueront jamais.
L'idée vient du fait que nous pouvons changer le titre de cette boîte de dialogue, cacher des fichiers et contourner le nom de fichier résultant assez facilement.
C'est un gros bidouillage, c'est sûr, mais peut-être que ça fera l'affaire pour votre usage ...
Dans cet exemple, j'ai un objet textbox pour contenir le chemin résultant, mais vous pouvez supprimer les lignes associées et utiliser une valeur de retour si vous le souhaitez ...
// 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;
}
Les seuls problèmes avec ce hack sont:
La plupart des gens ne le remarqueront pas, même si je préférerais définitivement utiliser un moyen officiel de WPF si Microsoft leur en retirait la tête, mais tant qu'ils ne le font pas, c'est ma solution temporaire.
J'ai trouvé le code ci-dessous sur le lien ci-dessous ... et cela a fonctionné Boîte de dialogue Sélectionner un dossier 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
}
Je suggérerais d'ajouter le paquet de pépites:
Install-Package OpenDialog
Alors la façon de l'utiliser est:
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();
Voici la documentation: http://opendialog.codeplex.com/documentation
Fonctionne pour les fichiers, les fichiers avec filtre, les dossiers, etc.
VistaFolderBrowserDialog
est celui que vous voulez.Si vous ne voulez que le navigateur de dossiers de Ooki Dialogs et rien d'autre alors téléchargez le fichier Source , sélectionnez les fichiers dont vous avez besoin pour le navigateur de dossiers (indice: 7 fichiers) et tout se passe bien sous .NET. 4.5.2. Je devais ajouter une référence à System.Drawing
. Comparez les références du projet original au vôtre.
Comment déterminez-vous quels fichiers? Ouvrez votre application et Ookii dans différentes instances de Visual Studio. Ajoutez VistaFolderBrowserDialog.cs
à votre application et continuez à ajouter des fichiers jusqu'à ce que les erreurs de génération disparaissent. Vous trouvez les dépendances dans le projet Ookii - Cliquez-droit sur celui que vous voulez suivre jusqu'à sa source (jeu de mots voulu).
Voici les fichiers dont vous avez besoin si vous êtes trop paresseux pour le faire ...
NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
COMGuids.cs
ErrorHelper.cs
ShellComInterfaces.cs
ShellWrapperDefinitions.cs
Modifiez la ligne 197 dans VistaFolderBrowserDialog.cs
sauf si vous souhaitez inclure leur Resources.Resx
lancer la nouvelle InvalidOperationException (Properties.Resources.FolderBrowserDialogNoRootFolder);
throw new InvalidOperationException("Unable to retrieve the root folder.");
Ajouter leur avis de droit d'auteur à votre application selon leur license.txt
Le code dans \Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs
ligne 160-169 est un exemple que vous pouvez utiliser, mais vous devrez supprimer this,
de MessageBox.Show(this,
pour WPF.
Fonctionne sur ma machine [TM]
Je sais que la question est ancienne, mais un moyen simple de le faire consiste à utiliser l'option FileDialog fournie par WPF et à utiliser System.IO.Path.GetDirectory (nom de fichier).
Aucune de ces réponses n'a fonctionné pour moi (généralement, il manquait une référence ou quelque chose du genre)
Mais cela tout simplement fait:
Utilisation de FolderBrowserDialog dans l'application WPF
Ajoutez une référence à System.Windows.Forms
et utilisez ce code:
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
Pas besoin de rechercher les paquets manquants. Ou ajouter des classes énormes
Cela me donne un sélecteur de dossier moderne qui vous permet également de créer un nouveau dossier.
Je n'ai pas encore vu l'impact lorsque déployé sur d'autres machines
Vous pouvez utiliser qch comme ceci dans WPF. J'ai créé la méthode exemple. Vérifiez ci-dessous.
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;
}