使用 Windows 应用 SDK 文件和文件夹选取器允许用户浏览和选择 WinUI 应用中的文件或文件夹。 选取器 API 提供熟悉的 Windows 体验,可帮助用户导航其设备和云存储位置。 本文介绍如何实现文件打开选取器和文件夹选取器、自定义其行为以及处理应用中所选结果。
Windows App SDK FileOpenPicker 和 FileSavePicker 类创建一个选取器对话框,允许用户指定要打开或保存的文件的名称和位置。 FolderPicker 类允许你选择文件夹。
若要了解如何使用选取器保存文件,请参阅 使用 Windows 应用 SDK 选取器保存文件。
重要 API
本文使用以下 API:
文件选择界面
文件选取器显示面向用户的信息,并在打开或保存文件时提供一致的体验。
这些信息包括:
- 当前位置
- 用户选取的项目
- 用户可以浏览到的位置树。 这些位置包括文件系统位置(如音乐或下载文件夹)以及实现文件选取器协定的应用(如相机、照片和Microsoft OneDrive)。
你可能有一个应用,允许用户打开或保存文件。 当用户执行该操作时,你的应用会调用文件选取器,以显示文件选取器用户界面。
选取器如何在你的应用中工作
使用选取器,你的应用可以访问、浏览和保存用户系统上的文件和文件夹。 你的应用接收这些选取作为轻型 PickFileResult 和 PickFolderResult 对象,这些对象提供所选文件或文件夹的路径。
选取器使用单个统一界面,让用户从文件系统或其他应用中选取文件和文件夹。 从其他应用选取的文件类似于文件系统中的文件。 一般情况下,你的应用可以像其他对象一样对它们进行作。 其他应用通过参与文件选取器协定来提供文件。
例如,可以在应用中调用文件选取器,以便用户可以打开文件。 此操作会使您的应用成为呼叫应用。 文件选取器与系统和其他应用交互,以便用户导航和选取文件。 当用户选择文件时,文件选取器会返回该文件的应用路径。
选择要打开示例的文件
以下代码演示如何使用 FileOpenPicker 类让用户选取单个文件,例如照片。 代码设置选取器的属性以自定义其外观和行为,然后使用 PickSingleFileAsync 方法向用户显示选取器。 如果用户选取文件,应用将读取文件的内容并将其存储在变量中。
using Microsoft.Windows.Storage.Pickers;
var openPicker = new FileOpenPicker(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 text displayed on the commit button.
// If not specified, the system uses a default label of "Open" (suitably translated).
CommitButtonText = "Choose selected files",
// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
FileTypeFilter = { ".txt", ".pdf", ".doc", ".docx" },
// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
ViewMode = PickerViewMode.List,
};
var result = await openPicker.PickSingleFileAsync();
if (result is not null)
{
var content = System.IO.File.ReadAllText(result.Path);
}
else
{
// Add your error handling here.
}
这与C++中的示例相同:
#include <winrt/Microsoft.Windows.Storage.Pickers.h>
#include <fstream>
#include <string>
using namespace winrt::Microsoft::Windows::Storage::Pickers;
FileOpenPicker openPicker(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.
openPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// (Optional) specify the text displayed on the commit button.
// If not specified, the system uses a default label of "Open" (suitably translated).
openPicker.CommitButtonText(L"Choose selected files");
// (Optional) specify file extension filters. If not specified, defaults to all files (*.*).
openPicker.FileTypeFilter().ReplaceAll({ L".txt", L".pdf", L".doc", L".docx" });
// (Optional) specify the view mode of the picker dialog. If not specified, defaults to List.
openPicker.ViewMode(PickerViewMode::List);
auto result{ co_await openPicker.PickSingleFileAsync() };
if (result)
{
std::ifstream fileReader(result.Path().c_str());
std::string text((std::istreambuf_iterator<char>(fileReader)), std::istreambuf_iterator<char>());
winrt::hstring hText = winrt::to_hstring(text);
}
else
{
// Add your error handling here.
}
选取多个文件以打开示例
还可以让用户选取多个文件。 以下代码演示如何使用 FileOpenPicker 类让用户选取多个文件,例如照片。 此过程相同,但 PickMultipleFilesAsync 方法返回文件路径的集合,而不是单个路径。
using Microsoft.Windows.Storage.Pickers;
var openPicker = new FileOpenPicker(this.AppWindow.Id);
var results = await openPicker.PickMultipleFilesAsync();
if (results.Count > 0)
{
var pickedFilePaths = results.Select(f => f.Path);
foreach (var path in pickedFilePaths)
{
var content = System.IO.File.ReadAllText(path);
}
}
else
{
// Add your error handling here.
}
若要在C++中执行相同的作,请使用以下代码:
#include <winrt/Microsoft.Windows.Storage.Pickers.h>
#include <fstream>
#include <string>
using namespace winrt::Microsoft::Windows::Storage::Pickers;
FileOpenPicker openPicker(this->AppWindow().Id());
auto results{ co_await openPicker.PickMultipleFilesAsync() };
if (results.Size() > 0)
{
for (auto const& result : results)
{
std::ifstream fileReader(result.Path().c_str());
std::string text((std::istreambuf_iterator<char>(fileReader)), std::istreambuf_iterator<char>());
winrt::hstring hText = winrt::to_hstring(text);
}
}
else
{
// Add your error handling here.
}
选取文件夹示例
若要使用 FolderPicker 类选取文件夹,请使用以下代码。 此代码创建文件夹选取器,使用 PickSingleFolderAsync 方法向用户显示文件夹,并在 PickFolderResult 对象中检索所选文件夹的路径。 如果用户选取文件夹,应用将检索文件夹的路径,并将其存储在变量中供以后使用。
using Microsoft.Windows.Storage.Pickers;
var folderPicker = new FolderPicker(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 text displayed on the commit button.
// If not specified, the system uses a default label of "Open" (suitably translated).
CommitButtonText = "Select Folder",
// (Optional) specify the view mode of the picker dialog. If not specified, default to List.
ViewMode = PickerViewMode.List,
};
var result = await folderPicker.PickSingleFolderAsync();
if (result is not null)
{
var path = result.Path;
}
else
{
// Add your error handling here.
}
若要在C++中执行相同的作,请使用以下代码:
#include <winrt/Microsoft.Windows.Storage.Pickers.h>
using namespace winrt::Microsoft::Windows::Storage::Pickers;
FolderPicker folderPicker(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.
folderPicker.SuggestedStartLocation(PickerLocationId::DocumentsLibrary);
// (Optional) specify the text displayed on the commit button.
// If not specified, the system uses a default label of "Open" (suitably translated).
folderPicker.CommitButtonText(L"Select Folder");
// (Optional) specify the view mode of the picker dialog. If not specified, default to List.
folderPicker.ViewMode(PickerViewMode::List);
auto result{ co_await folderPicker.PickSingleFolderAsync() };
if (result)
{
auto path{ result.Path() };
}
else
{
// Add your error handling here.
}
小窍门
每当应用通过选取器访问文件或文件夹时,请将其添加到应用的 FutureAccessList 或 MostRecentlyUsedList ,以使用 Windows 运行时 (WinRT) API 跟踪它。 有关详细信息,请参阅 如何跟踪最近使用的文件和文件夹。
文件夹选取器 UI 如下所示: