无论何时在几乎任何Windows应用程序中打开或保存文件,您都会看到大致相同的对话框。原因当然是这些对话框是Windows API的一部分,因此Windows平台上的开发人员也可以访问这些对话框。
对于WPF,您将找到用于在Microsoft.Win32命名空间中打开和保存文件的标准对话框。在本文中,我们将重点介绍OpenFileDialog类,这使得显示打开一个或多个文件的对话框变得非常容易。
让我们从没有任何额外选项的OpenFileDialog开始,将文件加载到TextBox控件:
<Window x:Class="WpfTutorialSamples.Dialogs.OpenFileDialogSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpenFileDialogSample" Height="300" Width="300">
<DockPanel Margin="10">
<WrapPanel HorizontalAlignment="Center" DockPanel.Dock="Top" Margin="0,0,0,10">
<Button Name="btnOpenFile" Click="btnOpenFile_Click">Open file</Button>
</WrapPanel>
<TextBox Name="txtEditor" />
</DockPanel>
</Window>
using System;
using System.IO;
using System.Windows;
using Microsoft.Win32;
namespace WpfTutorialSamples.Dialogs
{
public partial class OpenFileDialogSample : Window
{
public OpenFileDialogSample()
{
InitializeComponent();
}
private void btnOpenFile_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
if(openFileDialog.ShowDialog() == true)
txtEditor.Text = File.ReadAllText(openFileDialog.FileName);
}
}
}
单击“打开文件”按钮后,将实例化并显示OpenFileDialog。根据您使用的Windows版本和所选主题,它将如下所示:
ShowDialog()将返回一个可以为空的布尔值,这意味着它可以是false,true或null。如果用户选择文件并按“打开”,则结果为True,在这种情况下,我们尝试将文件加载到TextBox控件中。我们使用OpenFileDialog的FileName属性获取所选文件的完整路径。
通常,当您希望用户在应用程序中打开文件时,您希望将其限制为一种或几种文件类型。例如,Word主要打开Word文件(扩展名为.doc或.docx),而Notepad主要打开文本文件(扩展名为.txt)。
您可以为OpenFileDialog指定一个过滤器,以向用户指示应在应用程序中打开哪些类型的文件,以及限制显示的文件以获得更好的概述。这是通过Filter属性完成的,我们可以在初始化对话框后添加到上面的示例中,如下所示:
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
这是结果:
请注意对话框现在如何具有用于选择文件类型的组合框,并且所显示的文件仅限于具有所选文件类型指定的扩展名的文件。
用于指定过滤器的格式乍一看可能看起来有点奇怪,但它的工作原理是指定所需文件扩展名的人类可读版本,然后一个用于计算机轻松解析,用管道分隔(|)字符。如果您需要多个文件类型,就像我们在上面的示例中所做的那样,每组信息也用管道符分隔。
总而言之,以下部分意味着我们希望将文件类型命名为“文本文件(* .txt)”(括号中的扩展名是对用户的礼貌,因此他们知道包含哪些扩展名)第二部分告诉对话框显示扩展名为.txt的文件:
Text files (*.txt)|*.txt
每种文件类型当然可以有多个扩展名。例如,图像文件可以指定为JPEG和PNG文件,如下所示:
openFileDialog.Filter = "Image files (*.png;*.jpeg)|*.png;*.jpeg|All files (*.*)|*.*";
只需在第二部分(用于计算机的分号)中用分号分隔每个扩展名 - 在第一部分中,您可以按照您希望的方式对其进行格式化,但大多数开发人员似乎对两个部分使用相同的表示法,如上面的例子。
OpenFileDialog使用的初始目录由Windows决定,但通过使用InitialDirectory 属性,您可以覆盖它。您通常会将此值设置为用户指定的目录,应用程序目录或者可能只是上次使用的目录。您可以将其设置为字符串格式的路径,如下所示:
openFileDialog.InitialDirectory = @"c:\temp\";
如果要在Windows上使用某个特殊文件夹,例如在桌面,我的文档或程序文件目录中,您必须特别小心,因为这些可能因Windows的每个版本而异,也取决于登录的用户。但.NET框架可以帮助您,只需使用环境类及其成员处理特殊文件夹:
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
在这种情况下,我获取了My Documents文件夹的路径,但是看看了SpecialFolder枚举 - 它包含许多有趣路径的值。有关完整列表,请参阅此内容MSDN article.
如果您的应用程序支持多个打开的文件,或者您只是想使用OpenFileDialog一次选择多个文件,则需要启用Multiselect属性。在下一个例子中,我们已经做到了这一点,亲爱的读者,为了友好,我们还应用了上面提到的所有技术,包括过滤和设置初始目录:
<Window x:Class="WpfTutorialSamples.Dialogs.OpenFileDialogMultipleFilesSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="OpenFileDialogMultipleFilesSample" Height="300" Width="300">
<DockPanel Margin="10">
<WrapPanel HorizontalAlignment="Center" DockPanel.Dock="Top" Margin="0,0,0,10">
<Button Name="btnOpenFile" Click="btnOpenFiles_Click">Open files</Button>
</WrapPanel>
<ListBox Name="lbFiles" />
</DockPanel>
</Window>
using System;
using System.IO;
using System.Windows;
using Microsoft.Win32;
namespace WpfTutorialSamples.Dialogs
{
public partial class OpenFileDialogMultipleFilesSample : Window
{
public OpenFileDialogMultipleFilesSample()
{
InitializeComponent();
}
private void btnOpenFiles_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if(openFileDialog.ShowDialog() == true)
{
foreach(string filename in openFileDialog.FileNames)
lbFiles.Items.Add(Path.GetFileName(filename));
}
}
}
}
如果您测试此代码,您将看到现在可以通过按住 Ctrl或Shift并单击鼠标来选择同一目录中的多个文件。一旦被接受,此示例只需通过循环FileNames属性将文件名添加到ListBox控件。
正如您所看到的,在WPF中使用OpenFileDialog非常简单,而且大大简化了您的工作量。请注意,为了减少代码行数,在这些示例中不会进行异常处理。在处理文件和执行IO任务时,您应该始终注意因文件被锁定或者文件路径不存在等其他问题引发的异常。