1

私は Windows 8 の Metro スタイル アプリを使用しており、簡単に実行できるはずの作業に遭遇しましたが、解決策を見つけるのが非常に難しいと感じています。1 週間が経過しましたが、まだ解決策が見つからないため、有効な解決策として 300 担当者の報奨金を提供しています。

シナリオ:

テキスト ボックスを編集して [新しいドキュメントの作成] をクリックすると、新しいファイルを作成する前に既存のファイルに変更を保存するかどうかを尋ねるメッセージ ダイアログが表示されます。「はい、変更を保存します」をクリックすると、FileSavePicker が開き、ファイルを保存できます。

問題: [はい、変更を保存します] をクリックすると、ACCESSDENIED 例外が発生します。ブレークポイントを設定しましたが、例外の詳細から他の情報が明らかになりませんでした。

注:この場合は必須ではないため、DocumentsLibrary宣言を有効にしていません。これが機能しない場合は、とにかく有効にしようとしましたが、それでもエラーが発生しました。

また、コードのすべての部分は単独で (互いに分離して) 完全に機能しますが、すべてを結合すると、FileSavePicker を開こうとしたときにバラバラになります。

これはスレッドの問題である可能性があると思います。確信はないけど。

MSDN のMessageDialog 。

私が持っているコードは以下の通りです:

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

どうすればこれを機能させることができますか?

4

2 に答える 2

4

FileSavePicker問題は、MessageDialogが閉じられる前に (およびawait dialog.ShowAsync()通話が終了する前に) を開いていることのようです。この動作が発生する理由はわかりませんが、回避策は簡単に実行できます。例を作成するだけです。ニーズとモデルに合わせて調整するのはあなた次第です。

まず、 を宣言し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();
于 2013-01-07T06:18:32.440 に答える
1

メッセージ ダイアログが確実に終了するように、ファイル ピッカーを呼び出す前にわずかな遅延を導入できます。

await Task.Delay(10);
StorageFile file = await saver.PickSaveFileAsync();
于 2013-01-07T08:05:21.070 に答える