打开目录对话框

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打开目录对话框相关的知识,希望对你有一定的参考价值。

我希望用户选择一个目录,然后保存我将生成的文件。我知道在WPF中我应该使用Win32中的OpenFileDialog,但不幸的是对话框需要选择文件 - 如果我只是单击OK而不选择一个文件,它将保持打开状态。我可以通过让用户选择一个文件然后去除路径以找出它所属的目录来“破解”这个功能,但最好不直观。有没有人见过这个呢?

答案

您可以使用内置的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-Shellusing Microsoft.WindowsAPICodePack.Dialogs; ... var dialog = new CommonOpenFileDialog(); dialog.IsFolderPicker = true; CommonFileDialogResult result = dialog.ShowDialog(); 请注意,此对话框在Windows Vista之前的操作系统上不可用,因此请务必先检查CommonFileDialog.IsPlatformSupported
另一答案

The Ookii VistaFolderBrowserDialog is the one you want.

如果你只想要来自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

VistaFolderBrowserDialog.cs编辑第197行,除非你想包括他们的Resources.Resx

抛出新的InvalidOperationException(Properties.Resources.FolderBrowserDialogNoRootFolder);

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

根据他们的license.txt将他们的版权声明添加到您的应用中

Ookii.Dialogs.Wpf.SampleMainWindow.xaml.cs第160-169行中的代码是您可以使用的示例,但您需要从this,中删除MessageBox.Show(this,以获取WPF。

适用于我的机器[TM]

另一答案

我知道这是一个老问题,但一个简单的方法是使用WPF提供的FileDialog选项并使用System.IO.Path.GetDirectory(filename)。

另一答案

这些答案都不适用于我(通常有一个缺失的参考或类似的东西)

但这很简单:

Using FolderBrowserDialog in WPF application

添加对System.Windows.Forms的引用并使用以下代码:

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

无需追踪丢失的包裹。或者添加大量的课程

这给了我一个现代文件夹选择器,它还允许您创建一个新文件夹

我还没有看到部署到其他机器时的影响

另一答案

你可以在WPF中使用像这样的smth。我已经创建了示例方法。检查下面。

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;           
       }
另一答案

我创建了一个UserControl,使用如下:

  <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();
            }
        }
    }
 }
另一答案

我正在使用Ookii dialogs一段时间,它对WPF很有用。

这是直接页面:

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

另一答案

对于那些不想创建自定义对话框但仍然喜欢100%WPF方式并且不想使用单独的DDL,其他依赖项或过时的API的人,我想出了一个非常简单的黑客使用“另存为”对话框。

不需要使用指令,您可以简单地复制粘贴下面的代码!

它应该仍然是非常用户友好的,大多数人永远不会注意到。

这个想法来自于我们可以更改对话框的标题,隐藏文件以及轻松处理生成的文件名。

这肯定是一个很大的黑客,但也许它可以很好地满足你的使用......

在这个例子中,我有一个文本框对象来包含结果路径,但如果你愿意,你可以删除相关的行并使用返回值...

// 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;
}

这个黑客的唯一问题是: