我的应用有一个“打开文件”按钮。在启动OpenFileDialog之前,它会询问用户是否要保存当前文件,如果是,则启动SaveFileDialog。然后它启动OpenFileDialog。非常标准的东西。
我的问题是Silverlight然后看到OpenFileDialog.ShowDialog()方法不是用户启动的,我得到一个SecurityException。
有没有任何已知的合理方法可以避免此异常?当然这是一个非常标准的场景吗?
该应用在浏览器中。
欢迎任何想法
编辑:
抱歉,不允许发布实际代码:(逻辑非常简单:在伪造的代码中,'OpenFile'按钮按下事件会调用类似的方法:
*发出新的SL消息,询问是否先保存。
*在消息窗口中是/否点击: - 如果没有,请转到加载 - 如果是,启动SaveFileDialog.ShowDialog(),转到加载
*负载: 启动打开文件对话框
编辑2: 迷你程序......
主页的XML内容:
<Grid x:Name="LayoutRoot" Background="White">
<Button Content="Open" Click="Button_Click"/>
</Grid>
代码:
using System.Windows;
using System.Windows.Controls;
namespace SilverlightApplication15
{
public partial class MainPage : UserControl
{
AskWindow aw = new AskWindow();
public MainPage()
{
InitializeComponent();
aw.Closed += new System.EventHandler(aw_Closed);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
aw.Show();
}
private void aw_Closed(object sender, System.EventArgs e)
{
if (aw.DialogResult == true)
{
SaveFileDialog svd = new SaveFileDialog();
svd.ShowDialog();
}
OpenFileDialog ofd = new OpenFileDialog();
ofd.ShowDialog();//Causes security exception
}
}
public class AskWindow : ChildWindow
{
public AskWindow()
{
Button b = new System.Windows.Controls.Button();
b.Click += new System.Windows.RoutedEventHandler(b_Click);
b.Content = "Yes, save it";
this.Content = b;
}
private void b_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.DialogResult = true;
}
}
}
答案 0 :(得分:4)
对您的问题的简短回答是“NO”,导致第二个Dialog不再是用户启动的Silverlight运行时。如果在打开对话框之前显示MessageBox,情况也是如此。
以下是MSDN关于Dialogs安全限制的一些信息
出于安全考虑,如果Silverlight应用程序是沙盒应用程序,则必须由用户启动文件和打印对话框。这意味着您必须从用户启动的操作中显示它们,例如按钮的单击事件处理程序。如果您尝试从非用户启动的代码显示一个对话框,将发生SecurityException。此外,用户启动对话框和显示对话框之间的时间限制。如果超出这些操作之间的时间限制,则会发生异常。当您使用带有对话框的Visual Studio调试器时,如果在创建对话框和显示对话框之间设置断点,则将抛出SecurityException。由于用户启动的限制,这是预期的行为。如果在调用ShowDialog之后设置断点,则不会抛出任何异常。
如果尝试从KeyDown事件处理程序和对应用程序代码的其他同步调用(如LayoutUpdated或SizeChanged事件处理程序)显示对话框,则会引发异常。但是,当应用程序托管在Internet Explorer中并以受保护模式运行时,不会抛出异常。
当插件处于全屏模式时,Silverlight插件对对话框的支持有限。在大多数情况下,以全屏模式显示对话框将导致插件恢复为嵌入模式。但是,为了避免某些浏览器出现问题,您应该在使用这些类之前退出全屏模式。在浏览器外部运行的Silverlight应用程序中,您可以向用户显示提示,以在全屏模式下启用对话框。此外,对受信任的应用程序放宽了用户启动限制。有关更多信息,请参阅受信任的应用程序。
时间限制可以使用以下代码轻松测试:
private void OpenDialog(object sender, RoutedEventArgs e) {
MessageBox.Show("test");
OpenFileDialog fileDialog = new OpenFileDialog();
var result = fileDialog.ShowDialog();
}
当你在显示MessageBox时真正快速点击“Enter”-Key时,之后会显示OpenFileDialog,不会引发任何安全性异常。但是,如果您将MessageBox保持打开一小段时间,则在关闭MessageBox之后会引发SecurityException。
我认为时间限制是一个接一个地显示两个对话框的问题,因为时间限制将超过显示第一个。
答案 1 :(得分:3)
它可能是桌面应用程序的标准方案,但您不是在创建桌面应用程序。您正在创建一个在安全沙箱中运行的组件,并且出于某些相当严格的限制,这有充分的理由。
没有灵巧的方法来处理这种情况。您可以提供一个关闭的“文档”功能,该功能将弹出一个确认框,警告继续将丢失工作。
在尝试打开另一个“文档”而当前未保存时,您只能显示指示用户选择的消息,关闭当前“文档”并放弃其更改或选择保存。用户必须手动执行这些操作,然后再次选择打开“文档”。
如果您的应用支持多个“打开”文档,您可以稍微改进一下,至少不会因打开“文档”而对用户征税。
答案 2 :(得分:0)
您应立即在鼠标SaveFileDialog
处理程序中显示Click
。
在你的情况下,将在private void b_Click
。
在鼠标点击和SaveFileDialog
之间设置一些障碍是行不通的。