通过


教程:在 WinUI 中使用Windows App SDK选取器保存文件

使用Windows App SDK生成Windows应用时,用户通常需要将文档、图像或其他内容等文件保存到其设备上的特定位置。 Windows App SDK提供 FileSavePicker 类,以创建一致的用户友好界面,允许用户选择文件保存位置以及命名文件的名称。

本文介绍如何在 WinUI 应用中实现文件保存选取器。 你将了解如何配置选取器的外观和行为、处理用户的选择,以及如何将内容保存到所选位置。

可以使用建议的文件名和其他默认设置填充保存文件选取器,以便用户更轻松地保存其文件:

保存文件选取器屏幕截图,其中包含建议的文件名“我的文档”和文件类型“Documents”(.txt、.doc、.docx)。

先决条件

在开始之前,请确保具备:

  • 使用 Windows App SDK 设置的 WinUI 项目
  • 基本熟悉 C# 和 XAML
  • 了解 C# 中的异步与“await”模式

重要 API

本主题使用以下 API:

使用 FileSavePicker 允许用户指定他们希望你的应用保存文件的名称和位置。

使用 FileSavePicker 保存文档

使用 FileSavePicker ,以便用户可以指定要保存的文件的名称、类型和位置。 创建、自定义和显示文件选取器对象,然后通过返回的 StorageFile 对象保存数据,该对象表示已选取的文件。

  1. 创建并自定义 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",
    };
    #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");

此示例设置六个属性: SuggestedStartLocationSuggestedFileNameSuggestedFolderCommitButtonTextFileTypeChoicesDefaultFileExtension

由于用户正在保存文档或文本文件,因此示例使用 PickerLocationId 枚举中的 DocumentsLibrary 值将 SuggestedStartLocation 设置为文档库文件夹。 将 SuggestedStartLocation 设置为适合所保存文件类型的位置,例如音乐、图片、视频或文档。 从起始位置开始,用户可以导航到并选择其他位置。

为了减少用户的键入操作,该示例设置了SuggestedFileName。 建议的文件名应与所保存的文件相关。 例如,与Word一样,可以建议现有文件名(如果有)或文档的第一行(如果用户正在保存尚未具有名称的文件)。

在指定示例支持的文件类型(如 Microsoft Word 文档和文本文件)时,请使用 FileTypeChoices 属性。 这可确保应用在保存文件后可以打开该文件。 请确保应用支持你指定的所有文件类型。 用户将能够将其文件另存为你指定的任何文件类型。 它们还可以通过选择指定的另一种文件类型来更改文件类型。 默认情况下,将选择列表中的第一个文件类型。 若要控制该属性,请设置 DefaultFileExtension 属性。

注释

文件选取器还使用当前选定的文件类型来筛选它显示的文件,以便仅向用户显示与所选文件类型匹配的文件类型。

注释

FileSavePicker 对象使用 PickerViewMode.List 视图模式显示文件选取器。

  1. 接下来,显示 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.";
    }
    #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.");
    }

该示例检查文件是否存在,并创建一个新文件或追加到现有文件。 如果用户取消作,结果将是 null,你可以相应地处理该情况,例如向用户显示消息。

小窍门

应始终检查保存的文件,以确保该文件存在且在执行任何其他处理之前有效。 然后,可以根据应用将内容保存到文件。 如果选取的文件无效,应用应提供适当的行为。

Windows.Storage.Pickers

具有 Windows App SDK 的文件、文件夹和库

PickSaveFileAsync