2009-12-17 140 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)。