[Wpf] 打开目录对话框


Answers

我创建了一个像这样使用的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();
            }
        }
    }
 }
Question

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




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




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



Ookii VistaFolderBrowserDialog是你想要的。

如果你只需要Ooki Dialogs的文件夹浏览器,并且没有其他的东西,那么下载源文件,选择文件夹浏览器所需的文件(提示: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, MessageBox.Show(this,对于WPF。

适用于My Machine [TM]




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

PM> Install-Package OpenDialog

它非常适合MVVM,它不包含winforms对话框




对于要获取目录路径的目录对话框,首先添加引用System.Windows.Forms,然后解析,然后将此代码放在按钮单击中。

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

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

    string folder = dialog.SelectedPath;

如果您获取FileName /路径,只需在按钮单击上执行此操作

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

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

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