简体   繁体   English

用户单击MessageDialog上的按钮时如何调用FileSavePicker?

[英]How to call FileSavePicker when user clicks button on MessageDialog?

I have a Windows 8 Metro style app and I have run into what should be a simple thing to accomplish, but am finding it extremely difficult to come up with a solution. 我有一个Windows 8 Metro风格的应用程序,遇到了应该很简单的事情,但是发现解决方案非常困难。 As it's been a week now and I still haven't found a solution, I am offering a bounty of 300 rep for a working solution. 由于已经有一个星期了,但是我仍然没有找到解决方案,因此我提供300 rep的赏金来解决这个问题。

Scenario: 场景:

When I edit a textbox, and click Create New Document, a MessageDialog appears asking if I want to save changes to the existing file before creating a new one. 当我编辑一个文本框并单击“创建新文档”时,会出现一个MessageDialog,询问我是否要在创建新文件之前将更改保存到现有文件中。 If I click "Yes, save changes" - then the FileSavePicker opens, allowing me to save the file. 如果单击“是,保存更改”-然后FileSavePicker打开,允许我保存文件。

The Problem: When I click "Yes, save changes", I get an ACCESSDENIED exception. 问题:当我点击“是的,保存更改”,我得到一个存取遭拒例外。 I have set breakpoints but exception details have not revealed any other information. 我已经设置了断点,但是异常详细信息没有显示任何其他信息。

Notes: I do not have DocumentsLibrary declaration enabled because in this case that is not a requirement, and when this did not work, I then tried enabling it anyway - and I still got the error. 注意:我没有启用DocumentsLibrary声明,因为在这种情况下这不是必需的,并且当此方法不起作用时,无论如何我都尝试启用它-仍然出现错误。

Also, all pieces of code work perfectly on their own (separate from each other), but when you tie it all together, it falls apart when the FileSavePicker tried to open. 同样,所有代码段都可以完美地独立工作(彼此独立),但是当您将所有代码捆绑在一起时,当FileSavePicker尝试打开时,它们会崩溃。

I believe this may be a Threading issue. 我相信这可能是线程问题。 But I'm not sure. 但是我不确定。

MessageDialog on MSDN. MSDN上的MessageDialog

The code I have is below: 我的代码如下:

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();
}

} }

And the FileSavePicker stuff: 还有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);
    }
}

How can I get this to work? 我该如何工作?

The problem seems to be that you're opening a FileSavePicker before the MessageDialog is closed (and before the await dialog.ShowAsync() call is terminated). 问题似乎是您在关闭MessageDialog之前(以及在await dialog.ShowAsync()调用终止之前)打开了FileSavePicker I am not sure of why this behavior happens, but a workaround can be easily done. 我不确定为什么会发生这种现象,但是可以很容易地解决。 I'll only make an example, it will be up to you to adapt it to your needs and model. 我仅举一个例子,您可以根据自己的需要和模型来进行调整。

First, declare an Enum . 首先,声明一个Enum

enum SaveChoice
{
    Undefined,
    Save,
    DoNotSave
}

Then, create a field/property in your class. 然后,在您的课程中创建一个字段/属性。 Again, this is not the most wise design choice but it works as an example. 同样,这不是最明智的设计选择,但可以作为示例。

SaveChoice _currentChoice;

Then, modify your CommandInvokeHandler method: 然后,修改您的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;
    }
}

Finally, edit your New_Click method: 最后,编辑您的New_Click方法:

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

You can introduce a tiny delay before calling the file picker to ensure the message dialog has ended. 您可以在调用文件选择器之前引入一点延迟,以确保消息对话框已结束。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当用户单击按钮(而不是page_loadcomplete)时如何调用javascript方法? - How to call javascript method when user clicks on button(not on page_loadcomplete)? 将FileSavePicker与MessageDialog的IUICommand事件一起使用 - Using FileSavePicker with MessageDialog's IUICommand event 如何更改MessageDialog按钮文本 - How to change MessageDialog button text 当用户单击DropDown按钮时,如何不在DateTimePicker中显示日历 - How not to show calendar in the DateTimePicker when user clicks DropDown button 用户单击列表框项时如何显示按钮? - How to show button when the user clicks a listbox item? 需要在用户单击按钮时同时调用 JavaScript 函数和代码隐藏函数 - Need to call a JavaScript function and a code behind function at the same time when a user clicks a button 用户单击单选按钮时触发事件 - Firing an event when a user clicks a radio button 用户单击按钮时重定向到登录页面 - Redirecting to login page when user clicks a button 当用户单击asp按钮时,如何模拟键盘按钮的按下? - How do I simulate keyboard button press when the user clicks on asp button? 当用户单击asp.net中的浏览器后退按钮时,如何快速重定向页面 - How to redirect the page quickly when the user clicks the browser back button in asp.net
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM