从 UICommand / MessageDialog 启动 FilePicker 或 FolderPicker

Launching a FilePicker or FolderPicker from a UICommand / MessageDialog

当我的 Windows Store 应用程序启动时,我想提示用户使用 FolderPicker 选择本地存储文件夹并使用 FutureAccessList 保存它。我使用的提示符是 MessageDialog

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var messageDialog = new MessageDialog("Please pick a folder where you'd like to store your documents", "Choose storage");
    messageDialog.Commands.Clear();
    messageDialog.Commands.Add(new UICommand("OK", async (command) =>
    {
        await PickFolder();
    });
    await messageDialog.ShowAsync();
}

private async Task PickFolder()
{
    FolderPicker folderPicker = new FolderPicker();
    folderPicker.SuggestedStartLocation = PickerLocationId.Desktop;
    folderPicker.FileTypeFilter.Add(".txt");
    folder = await folderPicker.PickSingleFolderAsync();
    // lets just ignore cancellations for now
    StorageApplicationPermissions.FutureAccessList.AddOrReplace("MyFolder", folder);
}

此代码无效 - 我收到拒绝访问错误

Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

我认为使用 messageDialog.ShowAsync() 足以解决这个问题,但它似乎不起作用。有任何想法吗?

我是否必须放弃漂亮的 WinRT messageDialogs 以支持自产的东西?

MessageDialog 的命令在关闭前触发,当第一个模式对话框仍在运行时您无法打开第二个模式对话框。

您需要将对 PickFolder 的调用延迟到 MessageDialog 完成之后。由于无论如何您都在等待它,因此您可以在 ShowAsync 之后调用它。这里没有实际意义,因为 ok 是唯一的选项,但您可以打开选择的命令以在多个选项之间进行选择。

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var messageDialog = new MessageDialog("Please pick a folder where you'd like to store your documents", "Choose storage");
    messageDialog.Commands.Clear();
    UICommand okCommand = new UICommand("Ok");
    messageDialog.Commands.Add(okCommand);
    var cmd = await messageDialog.ShowAsync();
    if (cmd == okCommand)
    {
        await PickFolder();
    }
}

另一种选择是在调用 PickFolder 之前在 UICommand 处理程序中添加延迟(例如,通过在 Dispatcher.RunAsync 块中调用 PickFolder),以便 MessageDialog 可以关闭。