c# .net silverlight-3.0

c# - "Los diálogos deben ser iniciados por el usuario" con SaveFileDialog en Silverlight 3



.net silverlight-3.0 (5)

¿Qué hay de preguntar primero, antes de descargar? El mensaje de error parece sugerir que es la forma en que Silverlight desea que usted le solicite que se asegure de que sabe que un usuario solicitó la acción, y no le envía spam al usuario con ventanas emergentes.

Dejando a un lado el modelo de seguridad de Silverlight, prefiero no esperar a que finalice una descarga antes de que me pregunten dónde colocarla.

Estoy trabajando en una aplicación Silverlight 3 con C #. Me gustaría permitir que el usuario descargue una imagen de la aplicación Silverlight. Estoy usando SaveFileDialog para realizar la tarea de descarga de archivos. El flujo va de esta manera:

  1. El usuario hace clic en el botón Descargar en la aplicación SL.
  2. Llamada de servicio web invocada para obtener la imagen del servidor
  3. El controlador de eventos asíncronos OnCompleted de la llamada al método web se invoca y recibe la imagen binaria del servidor
  4. Dentro del controlador de eventos OnCompleted, SaveFileDialog solicitó al usuario que guarde la imagen en la computadora.
  5. Transmita la imagen al archivo en el disco duro del usuario.

Estoy usando el siguiente código en una función a la que se llama desde el controlador de eventos OnCompleted para cumplir con la solicitud de SaveFileDialog y luego transmitir al archivo.

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

El SaveFileDialog arrojaría el error "Los diálogos deben ser iniciados por el usuario". al invocar el método ShowDialog en el código anterior. ¿Qué podría faltar aquí? ¿Cómo superar esto?


Acabo de comenzar con Silverlight 4 y tuve el mismo problema. Parece que si crea manualmente controladores de eventos, se lanza la excepción de seguridad, incluso si el controlador de eventos está manejando un evento de clic de botón con los parámetros correctos, pero si usa la opción "crear un nuevo controlador de eventos" en el botón en Xaml bajo el evento click, el nuevo controlador de eventos, con el mismo código y parámetros ahora funciona ... esta es una de las muchas cosas "descorazonadas" que he encontrado desde que comencé la transición de WPF a Silverlight.


Como Keith mencionó, esto es por diseño. This tutorial proporciona un excelente ejemplo utilizando el código que usé para descargar un archivo del servidor de la manera "correcta". (Funciona en Silverlight 4 también)


Lo que significa este mensaje de error es que solo puede mostrar un SaveFileDialog en respuesta a un evento iniciado por el usuario, como hacer clic en un botón. En el ejemplo que describe, no muestra SaveFileDialog en respuesta a un clic, sino en respuesta a una solicitud http completada (que no se considera un evento iniciado por el usuario). Entonces, lo que debe hacer para que esto funcione es que, en el evento Completado de la solicitud http, muestre una IU al usuario que diga "descarga completada, haga clic aquí para guardar el archivo en su computadora", y cuando el usuario haga clic en este mensaje, muestre el SaveFileDialog.


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