我正在使用C#开发Silverlight 3应用程序。我想允许用户从Silverlight应用程序下载图像。我正在使用SaveFileDialog来执行文件下载任务。流程就是这样:
我在一个函数中使用以下代码,该函数从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方法时。我在这里可以缺少什么?如何克服这个?
答案 0 :(得分:20)
此错误消息的含义是您只能显示SaveFileDialog以响应用户启动的事件,例如单击按钮。在您描述的示例中,您没有显示SaveFileDialog以响应单击,而是响应已完成的http请求(不被视为用户启动的事件)。因此,要使其工作,您需要做的是,在http请求的Completed事件中,向用户显示一些UI,说“下载已完成,单击此处将文件保存到您的计算机”,以及当用户点击时在此消息上,显示SaveFileDialog。
答案 1 :(得分:5)
在下载之前先问一下怎么样?它似乎从错误消息中建议,这是Silverlight希望您提示确保它知道用户请求操作的方式,而不是用弹出窗口向用户发送消息。
除了Silverlight安全模型之外,我不想等到下载完成才会被问到放在哪里!
答案 2 :(得分:1)
正如基思所说,这是设计上的。 This教程使用代码提供了一个很好的例子,我用它以“正确”的方式从服务器下载文件。 (也适用于Silverlight 4)
答案 3 :(得分:1)
我刚开始使用Silverlight 4并遇到了同样的问题。似乎如果手动创建事件处理程序,则抛出安全性异常,即使事件处理程序正在处理具有正确参数的按钮单击事件,但是如果您在Xaml中的按钮上使用“创建新事件处理程序”选项在click事件下,新的事件处理程序,具有相同的代码和参数现在可以工作....这是我从开始从WPF过渡到Silverlight后遇到的许多“软件”事件之一。
答案 4 :(得分: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