3

個別に、すべてのコードは完全に機能します。ファイルを保存するためのスニペット、ファイルを保存するディレクトリを選択するためのスニペット、およびメッセージ ダイアログはうまく機能します。

しかし、すべてを結び付けると、アクセスが拒否されます。この場合、DocumentsLibrary 機能を使用する必要がないため、使用していませんが、問題が発生した後にこの機能を有効にすると、それが問題ではないことが確認されました。

シナリオ: ユーザーは、テキスト ボックスにテキストを入力した後、新しいドキュメントを作成したいと考えています。AMessageDialogが表示され、最初に既存のファイルに変更を保存するかどうかを尋ねられます。ユーザーは [はい (ファイルを保存)] をクリックします。

ここで、 によって発生したイベントを処理しますMessageDialog

IUICommand コマンド イベント ハンドラー内で、どのボタンがクリックされたかをテストし、それに応じて動作します。

私はswitchステートメントでこれを行いました:

switch(command.Label) {
   case "Yes":
   SaveFile(); // extension method containing save file code that works on its own
   break;
   case "No":
   ClearDocument();
   break;
   default:
   break;
}

これで、[はい] ボタンを除いて、各ケースがうまく機能します。[はい] をクリックすると、ファイルに保存するコードを含む e テンション メソッドが呼び出されます

はいボタンをクリックすると、ACCESS DENIED 例外が発生します。例外の詳細は何も明らかにしませんでした。

の使い方と関係があると思いますMesaageDialog。しかし、何時間も検索した後、ボタンが押されたFileSavePickerときにファイルを保存する方法のサンプルをまだ見つけていません。MesaageDialog

これをどのように行うべきかについてのアイデアはありますか?

コードで更新

ユーザーが AppBar の [新しいドキュメント] ボタンをクリックすると、次のメソッドが起動します。

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

0

この問題に関する進展はありますか?私は現在同じ問題を抱えています。MessageDialogイベントに秒が表示されている場合も、同じ問題が発生することがわかりましたIUICommand

私の解決策は、最初の操作をキャンセルすることです (最初のメッセージ ダイアログが表示されます)。ここで私が使用しているいくつかのコード(グローバルオブジェクトでアクセス可能です):

    private IAsyncInfo mActiveDialogOperation = null;
    private object mOperationMutex = new object();

    private void ClearActiveOperation(IAsyncInfo operation)
    {
        lock (mOperationMutex)
        {
            if (mActiveDialogOperation == operation)
                mActiveDialogOperation = null;
        }
    }

    private void SetActiveOperation(IAsyncInfo operation)
    {
        lock (mOperationMutex)
        {
            if (mActiveDialogOperation != null)
            {
                mActiveDialogOperation.Cancel();
            }

            mActiveDialogOperation = operation;
        }
    }

    public void StopActiveOperations()
    {
        SetActiveOperation(null);
    }

    public async void ShowDialog(MessageDialog dialog)
    {
        StopActiveOperations();

        try
        {
            IAsyncOperation<IUICommand> newOperation = dialog.ShowAsync();
            SetActiveOperation(newOperation);
            await newOperation;
            ClearActiveOperation(newOperation);
        }
        catch (System.Threading.Tasks.TaskCanceledException e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
        }
    }

したがって、MessageDialog を表示するたびに、ShowDialog を呼び出します。これにより、現在のダイアログがあればキャンセルされます (その後、TaskCanceledException が発生します)。

FileSavePicker を使用する場合は、PickSaveFileAsync を呼び出す前に StopActiveOperations を呼び出します。

これは機能しますが、私はそれが好きだとは言えません。何か間違ったことをしているような気がします。

于 2013-12-05T19:39:22.803 に答える
0

OK、今私はそれを理解しました:-)。ドキュメントには、UICommand で新しいポップアップ/ファイル ピッカーを表示しないことが明示的に記載されています。

http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.popups.messagedialog.showasync

これは悪い方法の例です:

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageDialog dialog = new MessageDialog("Press ok to show new dialog (the application will crash).");
        dialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(OnDialogOkTest1)));
        dialog.Commands.Add(new UICommand("Cancel"));

        await dialog.ShowAsync();
    }

    private async void OnDialogOkTest1(IUICommand command)
    {
        MessageDialog secondDialog = new MessageDialog("This is the second dialog");
        secondDialog.Commands.Add(new UICommand("OK"));

        await secondDialog.ShowAsync();
    }

これは正しい方法です:

    private async void Button_Click_1(object sender, RoutedEventArgs e)
    {
        MessageDialog dialog = new MessageDialog("Press ok to show new dialog");
        UICommand okCommand = new UICommand("OK");
        UICommand cancelCommand = new UICommand("Cancel");

        dialog.Commands.Add(okCommand);
        dialog.Commands.Add(cancelCommand);

        IUICommand response = await dialog.ShowAsync();

        if( response == okCommand )
        {
            MessageDialog secondDialog = new MessageDialog("This is the second dialog");
            secondDialog.Commands.Add(new UICommand("OK"));

            await secondDialog.ShowAsync();
        }
    }

かなり単純なことですが、これをもっと早く入手する必要がありました...

于 2013-12-08T08:04:35.540 に答える