Ich möchte, dass der Benutzer ein Verzeichnis auswählt, in dem eine Datei gespeichert wird, die ich dann generieren werde. Ich weiß, dass ich in WPF die OpenFileDialog
von Win32 verwenden sollte, aber leider erfordert das Dialogfeld die Auswahl der Datei (en) - es bleibt geöffnet, wenn ich einfach auf OK klicke, ohne eine auszuwählen. Ich könnte die Funktionalität "hacken", indem der Benutzer eine Datei auswählen und dann den Pfad entfernen kann, um herauszufinden, zu welchem Verzeichnis er gehört. Dies ist jedoch bestenfalls nicht intuitiv. Hat jemand das schon mal gesehen?
Sie können dafür die integrierte FolderBrowserDialog Klasse verwenden. Es macht nichts aus, dass es sich im Namespace System.Windows.Forms
befindet.
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}
Wenn das Fenster über einem WPF-Fenster modal sein soll, lesen Sie die Frage So verwenden Sie einen FolderBrowserDialog aus einer WPF-Anwendung .
EDIT: Wenn Sie etwas ausgefalleneres als den einfachen, hässlichen FolderBrowserDialog von Windows Forms suchen, gibt es einige Alternativen, mit denen Sie stattdessen den Vista-Dialog verwenden können:
Die Windows API Code Pack-Shell :
using Microsoft.WindowsAPICodePack.Dialogs;
...
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
Beachten Sie, dass dieses Dialogfeld nicht für Betriebssysteme verfügbar ist, die älter als Windows Vista sind. Überprüfen Sie daher unbedingt CommonFileDialog.IsPlatformSupported
.
Ich habe ein UserControl erstellt, das folgendermaßen verwendet wird:
<UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>
Die xaml-Quelle sieht folgendermaßen aus:
<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>
und der 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();
}
}
}
}
Ich benutze Ookii-Dialoge für eine Weile und es funktioniert Nice für WPF.
Hier ist die direkte Seite:
Fügen Sie für den Verzeichnisdialog zum Abrufen des Verzeichnispfads zunächst den Verweis System.Windows.Forms hinzu und klicken Sie dann auf Auflösen. Fügen Sie dann diesen Code in eine Schaltfläche ein.
var dialog = new FolderBrowserDialog();
dialog.ShowDialog();
folderpathTB.Text = dialog.SelectedPath;
(folderpathTB ist der Name der TextBox, in die ich den Ordnerpfad gesetzt habe, OR und kann ihn auch einer String-Variablen zuweisen, d. h.)
string folder = dialog.SelectedPath;
Und wenn Sie Dateinamen/Pfad erhalten, tun Sie dies einfach mit dem Button Click
FileDialog fileDialog = new OpenFileDialog();
fileDialog.ShowDialog();
folderpathTB.Text = fileDialog.FileName;
(folderpathTB ist der Name der TextBox, in die ich den Dateipfad gesetzt habe, OR und kann ihn auch einer String-Variablen zuweisen.)
Hinweis: Für den Ordnerdialog muss die Datei "System.Windows.Forms.dll" zum Projekt hinzugefügt werden, andernfalls funktioniert sie nicht.
Der Ookii-Ordnerdialog kann bei Nuget gefunden werden.
PM> Install-Package Ookii.Dialogs
Und Beispielcode ist wie folgt.
var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
textBoxFolderPath.Text = dialog.SelectedPath;
}
Der beste Weg, um das zu erreichen, was Sie möchten, ist die Erstellung einer eigenen WFP-basierten Steuerung oder die Verwendung einer Steuerung, die von anderen erstellt wurde
Warum ? weil die Verwendung des Winforms-Dialogfelds in einer Wpf-Anwendung spürbare Auswirkungen auf die Leistung hat (aus irgendeinem Grund)
Ich empfehle dieses Projekt
https://opendialog.codeplex.com/
oder Nuget:
PM> Install-Package OpenDialog
es ist sehr MVVM-freundlich und schließt den Winforms-Dialog nicht ein
Für diejenigen, die kein benutzerdefiniertes Dialogfeld erstellen möchten, aber dennoch eine 100% WPF-Methode bevorzugen und keine separaten DDLs, zusätzliche Abhängigkeiten oder veraltete APIs verwenden möchten, habe ich einen sehr einfachen Hack mit dem Dialogfeld "Speichern unter" gefunden.
Keine using-Direktive erforderlich, Sie können einfach den folgenden Code kopieren und einfügen!
Es sollte immer noch sehr benutzerfreundlich sein und die meisten Leute werden es nie bemerken.
Die Idee kommt von der Tatsache, dass wir den Titel dieses Dialogs ändern, Dateien ausblenden und den resultierenden Dateinamen ziemlich leicht umgehen können.
Es ist sicherlich ein großer Hack, aber vielleicht erledigt es die Arbeit gut für Ihren Einsatz ...
In diesem Beispiel habe ich ein Textfeldobjekt, das den resultierenden Pfad enthalten soll. Sie können jedoch die zugehörigen Zeilen entfernen und einen Rückgabewert verwenden, wenn Sie möchten ...
// 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;
}
Die einzigen Probleme mit diesem Hack sind:
Die meisten Leute werden dies nicht bemerken, obwohl ich es definitiv vorziehen würde, eine offizielle WPF-Methode zu verwenden, wenn sich Microsoft die Köpfe aus den Ärschen holen würde, aber bis dahin ist dies meine vorübergehende Lösung.
Ich habe den untenstehenden Code unter dem folgenden Link gefunden ... und es hat funktioniert Ordner auswählen Dialog 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
}
Ich würde vorschlagen, das Nugget-Paket hinzuzufügen:
Install-Package OpenDialog
Dann ist der Weg zum Gebrauch:
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();
Hier ist die Dokumentation: http://opendialog.codeplex.com/documentation
Funktioniert für Dateien, Dateien mit Filter, Ordnern usw
VistaFolderBrowserDialog
ist die, die Sie wollen.Wenn Sie nur den Folder Browser aus Ooki Dialogs und sonst nichts wollen, dann die Quelle herunterladen, wählen Sie die Dateien aus, die Sie für den Folder Browser benötigen (Hinweis: 7 Dateien), und es funktioniert in .NET 4.5.2. Ich musste einen Verweis auf System.Drawing
hinzufügen. Vergleichen Sie die Referenzen im ursprünglichen Projekt mit Ihren.
Wie finden Sie heraus, welche Dateien? Öffnen Sie Ihre App und Ihr Ookii in verschiedenen Visual Studio-Instanzen. Fügen Sie VistaFolderBrowserDialog.cs
zu Ihrer App hinzu und fügen Sie weitere Dateien hinzu, bis die Build-Fehler verschwinden. Sie finden die Abhängigkeiten im Ookii-Projekt - Klicken Sie mit der rechten Maustaste auf den Link, den Sie zurückverfolgen möchten (Wortspiel beabsichtigt).
Hier sind die Dateien, die Sie benötigen, wenn Sie zu faul sind ...
NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
COMGuids.cs
ErrorHelper.cs
ShellComInterfaces.cs
ShellWrapperDefinitions.cs
Bearbeiten Sie Zeile 197 in VistaFolderBrowserDialog.cs
, es sei denn, Sie möchten ihren Resources.Resx
einfügen.
neue InvalidOperationException auslösen (Properties.Resources.FolderBrowserDialogNoRootFolder);
throw new InvalidOperationException("Unable to retrieve the root folder.");
Fügen Sie Ihrer App den Copyright-Hinweis gemäß ihrem license.txt
hinzu.
Der Code in \Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs
-Zeile 160-169 ist ein Beispiel, das Sie verwenden können. Sie müssen jedoch this,
aus MessageBox.Show(this,
für WPF entfernen.
Funktioniert auf meinem Computer [TM]
Ich weiß, dass dies eine alte Frage ist, aber eine einfache Möglichkeit, dies zu tun, ist die FileDialog-Option von WPF und die Verwendung von System.IO.Path.GetDirectory (Dateiname).
Keine dieser Antworten funktionierte für mich (im Allgemeinen fehlte eine Referenz oder etwas in dieser Richtung)
Aber das tat einfach:
Verwenden von FolderBrowserDialog in der WPF-Anwendung
Fügen Sie einen Verweis auf System.Windows.Forms
hinzu und verwenden Sie diesen Code:
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
Keine Notwendigkeit, fehlende Pakete aufzuspüren. Oder fügen Sie riesige Klassen hinzu
Dies gibt mir eine moderne Ordnerauswahl, mit der Sie auch einen neuen Ordner erstellen können
Die Auswirkungen auf andere Maschinen sind noch nicht zu sehen
Sie könnten smth so in WPF verwenden. Ich habe eine Beispielmethode erstellt. Überprüfen Sie unten.
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;
}