使用 Windows 应用 SDK 生成 Windows 应用时,用户通常需要将文档、图像或其他内容等文件保存到其设备上的特定位置。 Windows 应用 SDK 提供 FileSavePicker 类,用于创建一致的用户友好界面,让用户选择保存文件的位置以及为其命名的内容。
本文介绍如何在 WinUI 应用中实现文件保存选取器。 你将了解如何配置选取器的外观和行为、处理用户的选择,以及如何将内容保存到所选位置。
可以使用建议的文件名和其他默认设置填充保存文件选取器,以便用户更轻松地保存其文件:
先决条件
在开始之前,请确保具备:
- 使用 Windows 应用 SDK 设置的 WinUI 项目
- 基本熟悉 C# 和 XAML
- 了解 C# 中的异步与“await”模式
重要 API
本主题使用以下 API:
使用 FileSavePicker 允许用户指定他们希望你的应用保存文件的名称和位置。
使用 FileSavePicker 保存文档
使用 FileSavePicker ,以便用户可以指定要保存的文件的名称、类型和位置。 创建、自定义和显示文件选取器对象,然后通过返回的 StorageFile 对象保存数据,该对象表示选取的文件。
创建并自定义 FileSavePicker。 首先创建新的 FileSavePicker 对象,然后在对象上设置属性以自定义应用和用户的文件选取器:
using Microsoft.Windows.Storage.Pickers; ... var savePicker = new FileSavePicker(this.AppWindow.Id) { // (Optional) Specify the initial location for the picker. // If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary. // If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location. SuggestedStartLocation = PickerLocationId.DocumentsLibrary, // (Optional) specify the default file name. If not specified, use system default. SuggestedFileName = "My Document", // (Optional) Sets the folder that the file save dialog displays when it opens. // If not specified or the specified path doesn't exist, defaults to the last folder the user visited. SuggestedFolder = @"C:\MyFiles", // (Optional) specify the text displayed on the commit button. // If not specified, the system uses a default label of "Save" (suitably translated). CommitButtonText = "Save Document", // (Optional) categorized extension types. If not specified, "All Files (*.*)" is allowed. // Note that when "All Files (*.*)" is allowed, end users can save a file without an extension. FileTypeChoices = { { "Documents", new List<string> { ".txt", ".doc", ".docx" } } }, // (Optional) specify the default file extension (will be appended to SuggestedFileName). // If not specified, no extension will be appended. DefaultFileExtension = ".txt", };此示例设置六个属性: SuggestedStartLocation、 SuggestedFileName、 SuggestedFolder、 CommitButtonText、 FileTypeChoices 和 DefaultFileExtension。
由于用户正在保存文档或文本文件,因此示例使用 PickerLocationId 枚举中的 DocumentsLibrary 值将 SuggestedStartLocation 设置为文档库文件夹。 将 SuggestedStartLocation 设置为适合所保存文件类型的位置,例如音乐、图片、视频或文档。 从起始位置开始,用户可以导航到并选择其他位置。
为了减少用户的键入操作,该示例设置了SuggestedFileName。 建议的文件名应与所保存的文件相关。 例如,与 Word 一样,可以建议现有文件名(如果有)或用户正在保存尚没有名称的文件时文档的第一行。
指定示例支持的文件类型(Microsoft Word 文档和文本文件)时,请使用 FileTypeChoices 属性。 这可确保应用在保存文件后可以打开该文件。 请确保应用支持你指定的所有文件类型。 用户将能够将其文件另存为你指定的任何文件类型。 它们还可以通过选择指定的另一种文件类型来更改文件类型。 默认情况下,将选择列表中的第一个文件类型。 若要控制该属性,请设置 DefaultFileExtension 属性。
注释
文件选取器还使用当前选定的文件类型来筛选它显示的文件,以便仅向用户显示与所选文件类型匹配的文件类型。
此示例的等效C++代码如下所示:
#include <winrt/Microsoft.Windows.Storage.Pickers.h> using namespace winrt::Microsoft::Windows::Storage::Pickers; FileSavePicker savePicker(AppWindow().Id()); // (Optional) Specify the initial location for the picker. // If the specified location doesn't exist on the user's machine, it falls back to the DocumentsLibrary. // If not set, it defaults to PickerLocationId.Unspecified, and the system will use its default location. savePicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary); // (Optional) specify the default file name. If not specified, use system default. savePicker.SuggestedFileName(L"NewDocument"); // (Optional) Sets the folder that the file save dialog displays when it opens. // If not specified or the specified path doesn't exist, defaults to the last folder the user visited. savePicker.SuggestedFolder = L"C:\\MyFiles", // (Optional) specify the text displayed on the commit button. // If not specified, the system uses a default label of "Save" (suitably translated). savePicker.CommitButtonText(L"Save Document"); // (Optional) categorized extension types. If not specified, "All Files (*.*)" is allowed. // Note that when "All Files (*.*)" is allowed, end users can save a file without an extension. savePicker.FileTypeChoices().Insert(L"Text", winrt::single_threaded_vector<winrt::hstring>({ L".txt" })); // (Optional) specify the default file extension (will be appended to SuggestedFileName). // If not specified, no extension will be appended. savePicker.DefaultFileExtension(L".txt");注释
FileSavePicker 对象使用 PickerViewMode.List 视图模式显示文件选取器。
接下来,让我们显示 FileSavePicker 并保存到选取的文件位置。 通过调用 PickSaveFileAsync 显示文件选取器。 用户指定名称、文件类型和位置并确认保存文件后, PickSaveFileAsync 将返回一个轻型 FilePickResult 对象,该对象包含已保存文件和文件名的路径。 如果对此文件具有读取和写入访问权限,则可以捕获和处理此文件。
using Microsoft.Windows.Storage.Pickers; ... var savePicker = new FileSavePicker(this.AppWindow.Id); var result = await savePicker.PickSaveFileAsync(); if (result != null) { if (!System.IO.File.Exists(result.Path)) { // Create a file and write to it. System.IO.File.WriteAllText(result.Path, "Hello world." + Environment.NewLine); } else { // Append to the existing file. System.IO.File.AppendAllText(result.Path, "Hello again." + Environment.NewLine); } } else { this.textBlock.Text = "Operation cancelled."; }该示例检查文件是否存在,并创建一个新文件或追加到现有文件。 如果用户取消作,结果将是
null,你可以相应地处理该情况,例如向用户显示消息。小窍门
应始终检查保存的文件,以确保该文件存在且在执行任何其他处理之前有效。 然后,可以根据应用将内容保存到文件。 如果选取的文件无效,应用应提供适当的行为。
下面是此 C# 示例的等效C++:
#include <winrt/Microsoft.Windows.Storage.Pickers.h> #include <fstream> #include <string> using namespace winrt::Microsoft::Windows::Storage::Pickers; FileSavePicker savePicker(AppWindow().Id()); auto result{ co_await savePicker.PickSaveFileAsync() }; if (result) { // Check if the file exists. if (!std::ifstream(result.Path().c_str())) { std::ofstream outFile(result.Path().c_str()); outFile << "Hello world."; outFile.close(); } else { // Append to the existing file. std::ofstream outFile(result.Path().c_str(), std::ios::app); outFile << "Hello again."; outFile.close(); } } else { textBlock().Text(L"Operation cancelled."); }