web-dev-qa-db-ja.com

「ダイアログはユーザーが開始する必要があります。」 Silverlight3のSaveFileDialogを使用

私はC#でSilverlight3アプリに取り組んでいます。ユーザーがSilverlightアプリから画像をダウンロードできるようにしたいと思います。 SaveFileDialogを使用してファイルのダウンロードタスクを実行しています。フローは次のようになります。

  1. ユーザーがSLアプリの[ダウンロード]ボタンをクリックします。
  2. サーバーから画像を取得するために呼び出されたWebサービス呼び出し
  3. Webメソッド呼び出しのOnCompleted非同期イベントハンドラーが呼び出され、サーバーからバイナリイメージを受信します
  4. OnCompletedイベントハンドラー内で、SaveFileDialogは、イメージをコンピューターに保存するようにユーザーに要求しました。
  5. 画像をユーザーのハードドライブ上のファイルにストリーミングします。

OnCompletedイベントハンドラーから呼び出される関数で次のコードを使用して、SaveFileDialogプロンプトを実行し、ファイルにストリーミングしています。

            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "JPG Files|*.jpg" + "|All Files|*.*";
            bool? dialogResult = dialog.ShowDialog();

            if (dialogResult == true)
            {
                using (Stream fs = (Stream)dialog.OpenFile())
                {
                    fs.Write(e.Result, 0, e.Result.Length);
                    fs.Close();
                }
            }

SaveFileDialogは、「ダイアログはユーザーが開始する必要があります」というエラーをスローします。上記のコードでShowDialogメソッドを呼び出す場合。ここで何が欠けている可能性がありますか?これを克服する方法は?

18
pencilslate

このエラーメッセージの意味は、ボタンのクリックなど、ユーザーが開始したイベントに応答してのみSaveFileDialogを表示できるということです。説明している例では、クリックに応答してSaveFileDialogを表示しているのではなく、完了したhttpリクエスト(ユーザーが開始したイベントとは見なされない)に応答して表示しています。したがって、これを機能させるために必要なことは、httpリクエストのCompletedイベントで、「ダウンロードが完了しました。ここをクリックしてファイルをコンピューターに保存してください」というUIをユーザーに表示し、ユーザーがクリックしたときに実行することです。このメッセージで、SaveFileDialogを表示します。

20
KeithMahoney

ダウンロードする前に、まず質問してみませんか?エラーメッセージから、ポップアップでユーザーにスパムを送信するのではなく、Silverlightがユーザーにアクションを要求したことを確認するように求める方法であることが示唆されているようです。

Silverlightセキュリティモデルはさておき、ダウンロードが完了するのを待たずに、どこに置くかを尋ねられます。

5
Ray Hayes
Private _syncContext As SynchronizationContext
Private mBigStream As Stream

 Private Sub btnSave_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnSave.Click
    Try
        Dim saveDialog As New SaveFileDialog

        saveDialog.Filter = "Word |*.doc"
        saveDialog.DefaultExt = ".doc"

        If saveDialog.ShowDialog() Then
            Try
                mBigStream = saveDialog.OpenFile()

                _syncContext = SynchronizationContext.Current

                oWebService.GetReportAsync(Params, ... , _syncContext)
            Catch ex As Exception
                MessageBox.Show("File busy.")
            End Try
        End If
    Catch ex As Exception
        LogError((New System.Diagnostics.StackTrace()).GetFrame(0).GetMethod().Name.ToString, Err.Description)
    End Try
End Sub

Private Sub oWebService_GetReportCompleted(sender As Object, e As MainReference.GetReportCompletedEventArgs) Handles oWebService.GetReportCompleted
    Try
        ' e.Result is byte()

        If e.Result IsNot Nothing Then
            If e.Result.Count > 0 Then
                _syncContext.Post(Sub()
                                      Try
                                          mBigStream.Write(e.Result, 0, e.Result.Length)

                                          mBigStream.Flush()
                                          mBigStream.Close()

                                          mBigStream.Dispose()

                                          mBigStream = Nothing
                                      Catch ex As Exception
                                          LogError((New System.Diagnostics.StackTrace()).GetFrame(0).GetMethod().Name.ToString, Err.Description)
                                      End Try
                                  End Sub, Nothing)

                _syncContext = Nothing
            End If
        End If
    Catch ex As Exception
        LogError((New System.Diagnostics.StackTrace()).GetFrame(0).GetMethod().Name.ToString, Err.Description)
    End Try
End Sub
1
Alex

Silverlight 4を使い始めたばかりで、同じ問題が発生しました。イベントハンドラーを手動で作成すると、イベントハンドラーが正しいパラメーターでボタンクリックイベントを処理している場合でも、セキュリティ例外がスローされるようですが、Xamlのボタンで[新しいイベントハンドラーを作成する]オプションを使用するとクリックイベントの下で、同じコードとパラメーターを持つ新しいイベントハンドラーが機能するようになりました。これは、WPFからSilverlightへの移行を開始してから私が遭遇した多くの「厄介な」ものの1つです。

1
Greg S

キースが述べたように、これは仕様によるものです。 This チュートリアルは、サーバーから「正しい」方法でファイルをダウンロードするために使用したコードを使用した優れた例を示しています。 (Silverlight 4でも動作します)

1
JumpingJezza