it-swarm.com.de

Verzeichnis öffnen

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?

242
Alexandra

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:

  • Bibliotheken von Drittanbietern, z. B. Ookii-Dialoge (.NET 3.5)
  • 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.

367
Heinzi

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();
            }
        }
    }
 }
37
adrianm

Ich benutze Ookii-Dialoge für eine Weile und es funktioniert Nice für WPF.

Hier ist die direkte Seite:

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

8
Rafael

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.

6
Zia Ur Rahman

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;
}
5
Youngjae

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

4
bigworld12

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 Bestätigungsschaltfläche sagt immer noch "Speichern" anstelle von "Verzeichnis auswählen", aber in einem Fall wie "Minen" "Speichern" Sie die Verzeichnisauswahl, damit es immer noch funktioniert ... 
  • Das Eingabefeld sagt immer noch "Dateiname" anstelle von "Verzeichnisname", aber wir können sagen, dass ein Verzeichnis ein Dateityp ist ... 
  • Es gibt immer noch eine Dropdown-Liste "Dateityp", aber der Wert besagt "Directory (* .this.directory)", und der Benutzer kann es nicht ändern. 

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. 

4
Olivier St-L

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
}
4
Saurabh Raoot

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

3
Jose Ortega

Die Ookii 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]

2
CAD bloke

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

2
Gregory Eaton

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

1
Nick.McDermaid

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;           
       }
0
koberone