select文件夹对话框WPF

我开发了一个WPF4应用程序,并在我的应用程序,我需要让用户select一个文件夹,应用程序将存储的东西(文件,生成的报告等)。

我的要求:

  • 能够查看标准文件夹树

  • 能够select一个文件夹

  • WPF外观和感觉,这个对话框必须看起来像为Windows Vista / 7而不是Windows 2000甚至Win9xdevise的现代应用程序的一部分。

据我所知,直到2010年(.Net 4.0)将不会有一个标准的文件夹对话框,但也许有一些版本4.0的变化?

或者所有剩下要做的是使用老派的WinForms对话框? 如果这是我需要的唯一方法,那我怎样才能使它更接近Vista / 7风格而不是Win9x?

在一些论坛上,我看到了这样的对话框的实现,但是在Windows 95上有着难看的图标。它看起来不太好看。

我很久以前在我的博客上写过关于WPF对通用文件对话框的支持真的很差(或者至less在3.5版本中没有检查过版本4) – 但是很容易解决这个问题。

您需要添加正确的清单到您的应用程序 – 这将给你一个现代风格的消息框和文件夹浏览器(WinForms FolderBrowserDialog),但不是WPF文件打开/保存对话框,这在3个职位(如果你不在乎关于解释和只想解决scheme直接到第三):

  • 为什么使用WPF获取旧式文件对话框和消息框?
  • 将设置一个清单解决我的WPF消息框样式问题?
  • XP和Vista风格的文件对话框和WPF的消息框所需的应用程序清单

幸运的是,打开/保存对话框是非常薄的Win32 API的包装,很容易调用正确的标志来获得Vista / 7样式(设置清单后)

  • Vista风格打开并保存WPF对话框(不使用Vista桥样本)

Pavel Yosifovich的Windows Presentation Foundation 4.5 Cookbook (第155页)中的“使用通用对话框”一节中说:

“怎么select文件夹(而不是文件)?WPF OpenFileDialog不支持。一种解决scheme是使用Windows窗体的FolderBrowseDialog类。另一个好的解决scheme是使用Windows API代码包。

我从Windows®API代码包(用于Microsoft®.NET Framework Windows API代码包)下载了API代码包:在哪里? ,然后添加到Microsoft.WindowsAPICodePack.dll和Microsoft.WindowsAPICodePack.Shell.dll引用到我的WPF 4.5项目。

例:

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 } 

Microsoft.Win32.OpenFileDialog是Windows上任何应用程序使用的标准对话框。 在.NET 4.0中使用WPF时,用户不会感到惊讶

该对话框在Vista中被更改。 .NET 3.0和3.5中的WPF仍然使用传统对话框,但在.NET 4.0中已经修复。 我只能猜测你开始这个线程,因为你正在看到那个旧的对话框。 这可能意味着你实际上正在运行一个目标为3.5的程序。 是的,Winforms包装没有得到升级,并显示Vista版本。 System.Windows.Forms.OpenFileDialog类,你需要添加一个对System.Windows.Forms的引用。

MVVM + WinForms FolderBrowserDialog作为行为

 public class FolderDialogBehavior : Behavior<Button> { public string SetterName { get; set; } protected override void OnAttached() { base.OnAttached(); AssociatedObject.Click += OnClick; } protected override void OnDetaching() { AssociatedObject.Click -= OnClick; } private void OnClick(object sender, RoutedEventArgs e) { var dialog = new FolderBrowserDialog(); var result = dialog.ShowDialog(); if (result == DialogResult.OK && AssociatedObject.DataContext != null) { var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.CanRead && p.CanWrite) .Where(p => p.Name.Equals(SetterName)) .First(); propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null); } } } 

用法

  <Button Grid.Column="3" Content="..."> <Interactivity:Interaction.Behaviors> <Behavior:FolderDialogBehavior SetterName="SomeFolderPathPropertyName"/> </Interactivity:Interaction.Behaviors> </Button> 

Blogpost: http ://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html

将Windows API代码包Shell添加到您的项目

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

基于Oyun的回答,最好使用FolderName的依赖项属性。 这允许(例如)绑定到子属性,这在原来不起作用。 此外,在我调整的版本中,对话框显示select初始文件夹。

在XAML中的用法:

 <Button Content="..."> <i:Interaction.Behaviors> <Behavior:FolderDialogBehavior FolderName="{Binding FolderPathPropertyName, Mode=TwoWay}"/> </i:Interaction.Behaviors> </Button> 

码:

 using System.Windows; using System.Windows.Forms; using System.Windows.Interactivity; using Button = System.Windows.Controls.Button; public class FolderDialogBehavior : Behavior<Button> { #region Attached Behavior wiring protected override void OnAttached() { base.OnAttached(); AssociatedObject.Click += OnClick; } protected override void OnDetaching() { AssociatedObject.Click -= OnClick; base.OnDetaching(); } #endregion #region FolderName Dependency Property public static readonly DependencyProperty FolderName = DependencyProperty.RegisterAttached("FolderName", typeof(string), typeof(FolderDialogBehavior)); public static string GetFolderName(DependencyObject obj) { return (string)obj.GetValue(FolderName); } public static void SetFolderName(DependencyObject obj, string value) { obj.SetValue(FolderName, value); } #endregion private void OnClick(object sender, RoutedEventArgs e) { var dialog = new FolderBrowserDialog(); var currentPath = GetValue(FolderName) as string; dialog.SelectedPath = currentPath; var result = dialog.ShowDialog(); if (result == DialogResult.OK) { SetValue(FolderName, dialog.SelectedPath); } } } 

只有这样的对话框是FileDialog 。 它是WinForms的一部分,但它实际上只是包装WinAPI标准OS文件对话框。 而且我不认为它是丑陋的,它实际上是操作系统的一部分,所以它看起来就像它运行的操作系统。

其他方面,没有什么可以帮助你。 你要么需要寻找第三方的实施,要么免费(我不认为有什么好处)或付费。