我希望用户选择一个目录,我将生成的文件将保存在其中。我知道在WPF中,我应该使用Win32中的OpenFileDialog,但不幸的是,对话框需要选择文件-如果我只是单击确定而不选择一个,它就会保持打开。我可以通过让用户选择一个文件,然后剥离路径以找出它属于哪个目录来“hack”该功能,但这充其量是不直观的。有人见过这种情况吗?


当前回答

Ookii对话框包括一个选择文件夹(而不是文件)的对话框:

https://github.com/ookii-dialogs

其他回答

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

对于目录对话框获取目录路径,首先添加引用System.Windows。表单,然后解析,然后把这个代码放在按钮点击。

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

(folderpathTB是文本框的名字,我想把文件夹路径,或者你可以把它分配给一个字符串变量也就是)

    string folder = dialog.SelectedPath;

如果你想获得文件名/路径,只需在按钮单击上这样做

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

(folderpathTB是文本框的名字,我想把文件路径,或者你可以把它分配给一个字符串变量太)

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Gearplay
{
    /// <summary>
    /// Логика взаимодействия для OpenFolderBrows.xaml
    /// </summary>
    public partial class OpenFolderBrows : Page
    {
        internal string SelectedFolderPath { get; set; }
        public OpenFolderBrows()
        {
            InitializeComponent();
            Selectedpath();
            InputLogicalPathCollection();
             
        }

        internal void Selectedpath()
        {
            Browser.Navigate(@"C:\");
            
            Browser.Navigated += Browser_Navigated;
        }

        private void Browser_Navigated(object sender, NavigationEventArgs e)
        {
            SelectedFolderPath = e.Uri.AbsolutePath.ToString();
            //MessageBox.Show(SelectedFolderPath);
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
          
           
        }
        
        string [] testing { get; set; }
        private void InputLogicalPathCollection()
        {            // add Menu items for Cotrol 
            string[] DirectoryCollection_Path = Environment.GetLogicalDrives(); // Get Local Drives
            testing = new string[DirectoryCollection_Path.Length];
            //MessageBox.Show(DirectoryCollection_Path[0].ToString());
            MenuItem[]  menuItems = new MenuItem[DirectoryCollection_Path.Length]; // Create Empty Collection
            for(int i=0;i<menuItems.Length;i++)
            {
                // Create collection depend how much logical drives 
                menuItems[i] = new MenuItem();
                menuItems[i].Header = DirectoryCollection_Path[i];
                menuItems[i].Name = DirectoryCollection_Path[i].Substring(0,DirectoryCollection_Path.Length-1);
                DirectoryCollection.Items.Add(menuItems[i]);
                menuItems[i].Click += OpenFolderBrows_Click;
                testing[i]= DirectoryCollection_Path[i].Substring(0, DirectoryCollection_Path.Length - 1);
            }

            

        }
        
        private void OpenFolderBrows_Click(object sender, RoutedEventArgs e)
        {

            foreach (string str in testing)
            {
                if (e.OriginalSource.ToString().Contains("Header:"+str)) // Navigate to Local drive
                {
                    Browser.Navigate(str + @":\");
                   
                }


            }


        }

        private void Goback_Click(object sender, RoutedEventArgs e)
        {// Go Back
            try
            {
                Browser.GoBack();
            }catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Goforward_Click(object sender, RoutedEventArgs e)
        { //Go Forward
            try
            {
                Browser.GoForward();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void FolderForSave_Click(object sender, RoutedEventArgs e)
        {
            // Separate Click For Go Back same As Close App With send string var to Main Window ( Main class etc.) 
            this.NavigationService.GoBack();
        }
    }
}

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

我建议,在黄金套餐中加入:

  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

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