2009-08-30 22 views
18

私はC#でSilverlight 3アプリケーションを開発中です。ユーザーがSilverlightアプリケーションから画像をダウンロードできるようにしたいと思います。 SaveFileDialogを使用してファイルのダウンロードタスクを実行しています。フローは次のようになります。"ダイアログはユーザーが開始する必要があります。 SaveFileDialog with Silverlight 3

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

私は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メソッドを呼び出すとき私はここで何が欠けていますか?これを克服する方法は?

答えて

19

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

+8

私は、新しいSaveFileDialog()を呼び出す前にメソッドでいくつかの検証を行っていたので、Button_Clickイベントハンドラから直接SaveFileDialogを使用しようとしたのと同じエラーメッセージが表示されました。以下のJumpingJezzaのリンクは良い例ですが、ボタンイベントハンドラの* First *行として新しいSaveFileDialog()を持つことが鍵です。その後、あなたは一見あなたが好きなことをすることができます。 – Jedidja

+0

"最初の"行は実際には_first_を意味します。私は誰かのelsesコードをデバッグしていましたが、ボタンクリックイベントハンドラ内のコメント付きコードブロックが上記の例外を引き起こしました。 – faester

+2

私はこれがむしろ、保存された開店の前の時間の問題だと思います。 dialog.ShowDialog()の前にブレークポイントを置くと、エラーが発生します。 http://dotnetslang.wordpress.com/2011/03/12/using-the-savefiledialog-dialogs-must-be-user-initiated-exception/ – maxence51

5

ダウンロードする前に、最初に尋ねるのはどうですか?これは、エラーメッセージから、Silverlightがユーザーがアクションを要求したことを確認するように促す方法であり、ポップアップを使用してユーザーをスパイミングさせることではないと示唆しているようです。

Silverlightセキュリティモデルを別にして、どこに置くのが尋ねられる前に、ダウンロードが完了するのを待っていません!

1

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

+1

を参照してください。ボタンイベントハンドラでSaveFileDialogを作成することもできます。キーは、コンストラクタがメソッドの最初の行であることを確認することです。 – Jedidja

1

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

1
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 
+2

答えをより詳しく説明できますか?答えはc/pコードだけでなく、方向性を提供する必要があります。 – CodeMouse92

関連する問題