2009-12-17 149 views
218

我希望用戶選擇一個目錄,其中將生成一個我將生成的文件將被保存。我知道在WPF中,我應該使用Win32中的OpenFileDialog,但不幸的是,該對話框需要選擇文件 - 如果我只是單擊「確定」而不選擇文件,它將保持打開狀態。我可以通過讓用戶選擇一個文件來「破解」功能,然後剝離路徑以找出它屬於哪個目錄,但這最多是不直觀的。有沒有人見過這樣做?打開目錄對話框

+0

可能的[選擇文件夾對話框WPF]的副本(http://stackoverflow.com/questions/4007882/select-folder-dialog-wpf) – 2016-05-09 16:03:35

+0

請看這裏http://stackoverflow.com/questions/4007882/ select-folder-dialog-wpf – 2016-05-09 16:03:55

回答

327

您可以使用內置的FolderBrowserDialog類。不要介意它在System.Windows.Forms命名空間中。

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

如果你想窗口將超過一些WPF窗口模式,看到問題How to use a FolderBrowserDialog from a WPF application


編輯:如果你想要的東西有點比平原更看中的,醜陋的Windows窗體的FolderBrowserDialog,也有一些替代方案,允許您使用Vista,而不是對話:

  • 第三 - 第三方庫,如Ookii dialogs(.NET 3.5)
  • Windows API Code Pack-Shell

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

    請注意,此對話框在Windows Vista之前的操作系統上不可用,因此請務必首先檢查CommonFileDialog.IsPlatformSupported

+65

請注意,這是一個糟糕的對話框。您無法複製並粘貼路徑,也不支持收藏夾。總體而言,我會給它一個0分,並建議沒有人使用它。除非Windows Vista出現[更好的文件夾對話框](http://www.ookii.org/software/dialogs/images/folderbrowserdialog.png),否則沒有合理的選擇。有[良好的免費庫](http://www.ookii.org/software/dialogs/),顯示Vista +上的良好對話,以及XP上的壞對話。 – 2011-12-26 22:51:18

+8

Ookii對話框不在.NET 4下編譯。 – 2012-06-28 06:33:28

+0

@MohamedSakherSawan:您不需要使用Windows窗體,只需使用System.Windows.Forms命名空間中的類即可。 – Heinzi 2013-01-12 22:21:27

32

我創建其中使用這樣一個用戶控件:

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

的XAML源看起來像這樣:

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

和代碼隱藏

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(); 
      } 
     } 
    } 
} 
+1

+1,這是一個很好的例子,介紹如何編寫UserControl。一個問題:爲什麼你需要'be.UpdateSource'?不應該在依賴項屬性中自動更改通知? – Heinzi 2009-12-17 15:14:56

+0

文本框綁定僅在lostfocus事件中更新。 – adrianm 2009-12-17 15:34:47

+4

您可以在綁定中指定何時觸發更新。默認情況下,它位於LostFocus上,但您可以告訴它在PropertyChanged上觸發更新。 – Alexandra 2009-12-17 16:52:39

3

達到你想要的是創建自己的WPF爲基礎的控制,或使用被其他人做了一個最好的辦法
爲什麼呢?

PM> Install-Package OpenDialog 

這是非常MVVM友好,它不是由於使用了
我推薦這個項目
https://opendialog.codeplex.com/
或的NuGet中的WinForms在WPF應用程序對話框(由於某種原因)的時候會有一個顯着的性能影響't打包winforms對話框

4

對於目錄對話框來獲取目錄路徑,首先添加引用System.Windows.Forms,然後解析,然後將此代碼放在一個按鈕中單擊。

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

(folderpathTB是文本框的名字,我瓦納把文件夾路徑,或U可以將其分配給一個字符串變量也即)

string folder = dialog.SelectedPath; 

如果你瓦納獲取文件名/路徑,簡單地做這個按鈕點擊

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

(folderpathTB是文本框的名字,我瓦納把文件路徑,或U可以將其分配給一個字符串變量太)

注意:對於文件夾對話框,必須將System.Windows.Forms.dll添加到項目中,否則將無法工作。

+0

感謝您的回答,但此方法已由上面的@Heinzi解釋。 – Alexandra 2015-11-10 20:12:42

2

在Nuget上可以找到Ookii文件夾對話框。

PM> Install-Package Ookii.Dialogs

而且,示例代碼如下所示。

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog(); 
if (dialog.ShowDialog(this).GetValueOrDefault()) 
{ 
    textBoxFolderPath.Text = dialog.SelectedPath; 
} 
4

我發現下面的鏈接下面的代碼...和它的工作 Select folder 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 
} 
1

的Ookii VistaFolderBrowserDialog是你想要的。

如果你只想要Ooki Dialogs的文件夾瀏覽器,沒有別的,然後download the Source櫻桃選擇文件夾瀏覽器所需的文件(提示:7個文件),它在.NET 4.5.2中建立良好。我不得不添加對System.Drawing的引用。將原始項目中的參考文獻與您的項目進行比較。

你怎麼知道哪些文件?在不同的Visual Studio實例中打開您的應用程序和Ookii。將VistaFolderBrowserDialog.cs添加到您的應用程序並不斷添加文件,直到構建錯誤消失。您可以在Ookii項目中找到依存關係 - 控制 - 單擊您想要追溯到其源的項目(雙關意圖)。

下面是如果你懶得做,你需要的文件......

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

編輯線197 VistaFolderBrowserDialog.cs,除非你想包括其Resources.Resx

拋出新的InvalidOperationException異常( Properties.Resources.FolderBrowserDialogNoRootFolder);

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

加入他們的版權通知您的應用程序按他們的license.txt

中的代碼\Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs行160-169是你可以用一個例子,但你需要從MessageBox.Show(this,刪除this,爲WPF。

作品在我的機器[TM]

1

我建議,在金塊包添加:

Install-Package OpenDialog 

然後用它的方式是:

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

這裏的該文檔: http://opendialog.codeplex.com/documentation

適用於文件,文件wi個過濾器,文件夾等

0

這些答案都不對工作對我來說(通常有一個丟失的引用或類似的規定)

但是,這壓根兒:

Using FolderBrowserDialog in WPF application

添加到System.Windows.Forms參考,使用此代碼:

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

無需追查丟失的包。或增加巨大類

這給了我一個現代的文件夾選擇器,也可以讓你創建一個新的文件夾

我還沒有看到影響,在部署到其他機器

1

我知道這是一個老問題,但一個簡單的方法是使用WPF提供的FileDialog選項並使用System.IO.Path.GetDirectory(filename)。