首页 文章

打开目录对话框

提问于
浏览
238

我希望用户选择一个目录,然后保存我将生成的文件 . 我知道在WPF中我应该使用Win32中的 OpenFileDialog ,但不幸的是,对话框需要选择文件 - 如果我只是单击“确定”而不选择一个文件,它将保持打开状态 . 我可以通过让用户选择一个文件然后去除路径以确定它属于哪个目录但这最不直观的功能来实现功能.1402932_ . 以前有人见过这个吗?

13 回答

  • 4

    您可以使用内置的FolderBrowserDialog类来实现此目的 . 在 System.Windows.Forms 命名空间中输入't mind that it' .

    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 .


    EDIT: 如果你想要一些比简单,丑陋的Windows Forms FolderBrowserDialog更有趣的东西,有一些替代方案允许你使用Vista对话框:

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

    请注意,此对话框在Windows Vista之前的操作系统上不可用,因此请务必先检查 CommonFileDialog.IsPlatformSupported .

  • 35

    我创建了一个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();
                }
            }
        }
     }
    
  • 1

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

    这是直接页面:

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

  • 8

    对于目录对话框以获取目录路径,首先添加引用System.Windows.Forms,然后单击Resolve,然后将此代码放入按钮单击中 .

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

    (folderpathTB是TextBox的名称,我将wana放在文件夹路径中,或者你也可以将它分配给字符串变量,即)

    string folder = dialog.SelectedPath;
    

    如果您获得FileName / path,只需在Button Click上执行此操作

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

    (folderpathTB是我在wana放置文件路径的TextBox的名称,或者你也可以将它分配给字符串变量)

    注意:对于文件夹对话框,必须将System.Windows.Forms.dll添加到项目中,否则它将无法正常工作 .

  • 3

    可以在Nuget找到Ookii文件夹对话框 .

    PM> Install-Package Ookii.Dialogs

    并且,示例代码如下 .

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

    实现您想要的最佳方法是创建自己的基于wpf的控件,或者使用由其他人制作的控件
    为什么?因为在wpf应用程序中使用winforms对话框时会有明显的性能影响(由于某种原因)
    我推荐这个项目
    https://opendialog.codeplex.com/
    或Nuget:

    PM> Install-Package OpenDialog
    

    它非常友好的MVVM,并没有包装winforms对话框

  • 5

    我在下面的链接中找到了以下代码......它起作用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
    }
    
  • 3

    我建议,添加块金包:

    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

    适用于文件,带过滤器的文件,文件夹等

  • 4

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

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

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

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

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

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

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

    这个黑客的唯一问题是:

    • 确认按钮仍然显示"Save"而不是"Select directory"之类的东西,但是在类似地雷的情况下我"Save"目录选择所以它仍然有效......

    • 输入字段仍然显示"File name"而不是"Directory name",但我们可以说目录是一种文件...

    • 仍有"Save as type"下拉列表,但其值为"Directory (*.this.directory)",用户无法更改其他内容,对我有用...

    大多数人都不会注意到这些,虽然我绝对更喜欢使用正式的WPF方式,如果微软会从他们的屁股中脱颖而出,但直到他们这样做,这是我的临时修复 .

  • 2

    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
    

    编辑 VistaFolderBrowserDialog.cs 中的第197行,除非您要包含他们的 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, for WPF .

    适用于我的机器[TM]

  • 2

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

  • 360

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

    但这很简单:

    Using FolderBrowserDialog in WPF application

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

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

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

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

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

  • 0

    你可以在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;           
           }
    

相关问题