任何绕过“对话必须是用户启动的”例外的方法?

时间:2011-11-04 10:01:55

标签: c# silverlight openfiledialog savefiledialog

我的应用有一个“打开文件”按钮。在启动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;
    }
}
}

3 个答案:

答案 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之间设置一些障碍是行不通的。