【问题标题】:How to call FileSavePicker when user clicks button on MessageDialog?当用户单击 MessageDialog 上的按钮时如何调用 FileSavePicker?
【发布时间】:2012-11-26 09:16:30
【问题描述】:

我有一个 Windows 8 Metro 风格的应用程序,我遇到了应该很容易完成的事情,但我发现想出一个解决方案非常困难。由于已经一个星期了,但我仍然没有找到解决方案,因此我提供 300 个代表的赏金来获得一个可行的解决方案。

场景:

当我编辑文本框并单击创建新文档时,会出现一个消息对话框,询问我是否要在创建新文件之前保存对现有文件的更改。如果我单击“是,保存更改” - 然后 FileSavePicker 将打开,允许我保存文件。

问题: 当我单击“是,保存更改”时,我得到一个 ACCESSDENIED 异常。我设置了断点,但异常细节没有透露任何其他信息。

注意事项: 我没有启用 DocumentsLibrary 声明,因为在这种情况下这不是必需的,当这不起作用时,我还是尝试启用它 - 但我仍然收到错误。

此外,所有代码片段都可以完美地独立运行(彼此分开),但是当您将它们捆绑在一起时,当 FileSavePicker 尝试打开时,它就会分崩离析。

我相信这可能是线程问题。但我不确定。

MessageDialog 在 MSDN 上。

我的代码如下:

async private void New_Click(object sender, RoutedEventArgs e)
{
    if (NoteHasChanged)
    {
        // Prompt to save changed before closing the file and creating a new one.
        if (!HasEverBeenSaved)
        {

        MessageDialog dialog = new MessageDialog("Do you want to save this file before creating a new one?",
            "Confirmation");
        dialog.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(this.CommandInvokedHandler)));
        dialog.Commands.Add(new UICommand("No", new UICommandInvokedHandler(this.CommandInvokedHandler)));
        dialog.Commands.Add(new UICommand("Cancel", new UICommandInvokedHandler(this.CommandInvokedHandler)));

        dialog.DefaultCommandIndex = 0;
        dialog.CancelCommandIndex = 2;

        // Show it.
        await dialog.ShowAsync();
    }
    else { }
}
else
{
    // Discard changes and create a new file.
    RESET();
}

}

还有 FileSavePicker 的东西:

private void CommandInvokedHandler(IUICommand command)
{
    // Display message showing the label of the command that was invoked
    switch (command.Label)
    {
        case "Yes":

            MainPage rootPage = this;
            if (rootPage.EnsureUnsnapped())
            {
                // Yes was chosen. Save the file.
                SaveNewFileAs();
            }
            break;
        case "No":
            RESET(); // Done.
            break;
        default:
            // Not sure what to do, here.
            break;
    }
}

async public void SaveNewFileAs()
{
    try
    {
        FileSavePicker saver = new FileSavePicker();
        saver.SuggestedStartLocation = PickerLocationId.Desktop;
        saver.CommitButtonText = "Save";
        saver.DefaultFileExtension = ".txt";
        saver.FileTypeChoices.Add("Plain Text", new List<String>() { ".txt" });

        saver.SuggestedFileName = noteTitle.Text;

        StorageFile file = await saver.PickSaveFileAsync();
        thisFile = file;

        if (file != null)
        {
            CachedFileManager.DeferUpdates(thisFile);

            await FileIO.WriteTextAsync(thisFile, theNote.Text);

            FileUpdateStatus fus = await CachedFileManager.CompleteUpdatesAsync(thisFile);
            //if (fus == FileUpdateStatus.Complete)
            //    value = true;
            //else
            //    value = false;

        }
        else
        {
            // Operation cancelled.
        }

    }
    catch (Exception exception)
    {
        Debug.WriteLine(exception.InnerException);
    }
}

我怎样才能让它工作?

【问题讨论】:

  • 如果我的回答令人满意,请考虑关闭赏金。
  • @Eve 我以为我已经这样做了。对此感到抱歉。

标签: c# .net windows-8 microsoft-metro


【解决方案1】:

问题似乎是您在关闭MessageDialog 之前(以及在终止await dialog.ShowAsync() 调用之前)打开了FileSavePicker。我不确定为什么会发生这种行为,但可以轻松完成解决方法。我只是举个例子,你可以根据自己的需要和模型来调整它。

首先,声明一个Enum。

enum SaveChoice
{
    Undefined,
    Save,
    DoNotSave
}

然后,在您的类中创建一个字段/属性。同样,这不是最明智的设计选择,但它可以作为示例。

SaveChoice _currentChoice;

然后,修改你的CommandInvokeHandler 方法:

void CommandInvokedHandler(IUICommand command)
{
    // Display message showing the label of the command that was invoked
    switch (command.Label)
    {
        case "Yes":
            var rootPage = this;
            if (rootPage.EnsureSnapped())
                _currentChoice = SaveChoice.Save;
            break;
        case "No":
            _currentChoice = SaveChoice.DoNotSave;
            break;
        default:
            _currentChoice = SaveChoice.Undefined;
            // Not sure what to do, here.
            break;
    }
}

最后,编辑你的New_Click 方法:

//Continues from dialog.CancelCommandIndex = 2;
// Show it.
await dialog.ShowAsync();
if (_currentChoice == SaveChoice.Save) SaveNewFileAs();

【讨论】:

    【解决方案2】:

    您可以在调用文件选择器之前引入一点延迟,以确保消息对话框已结束。

    await Task.Delay(10);
    StorageFile file = await saver.PickSaveFileAsync();
    

    【讨论】:

      猜你喜欢
      • 2016-11-19
      • 2023-04-02
      • 1970-01-01
      • 2014-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多