Любой способ обойти исключение "Диалоги должны быть инициированы пользователем"?

В моем приложении есть кнопка "открыть файл". Перед запуском OpenFileDialog, он спрашивает, хочет ли пользователь сохранить текущий файл, и если они это сделают, он запускает SaveFileDialog. Затем он запускает OpenFileDialog. Довольно стандартный материал.

Моя проблема в том, что Silverlight затем видит метод OpenFileDialog.ShowDialog() как не инициированный пользователем, и я получаю исключение SecurityException.

Есть ли какой-либо известный разумный способ избежать этого исключения? Конечно, это довольно стандартный сценарий?

Приложение находится в браузере.

Любые идеи приветствуются

EDIT:

Извините, не разрешено выпустить фактический код:( Логика довольно проста: в psuedocode кнопка "OpenFile" нажимает событие, вызывает метод вроде:

* Запустите новое сообщение SL с просьбой сохранить сначала.

* В окне сообщений да/нет: -Если нет, перейдите к загрузке -Если Да, запустите SaveFileDialog.ShowDialog(), перейдите в Load

* Нагрузка: Запустить диалоговое окно "Открыть файл"

ИЗМЕНИТЬ 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;
    }
}
}

Ответ 1

Это может быть стандартный сценарий для настольного приложения, но вы не создаете настольное приложение. Вы создаете компонент, который работает в безопасной песочнице, и это связано с некоторыми довольно строгими ограничениями по уважительным причинам.

Невозможно обработать этот сценарий. Вы можете предоставить закрытую функцию "document", которая выведет окно подтверждения, предупреждающее, что продолжающаяся потеряет работу.

При попытке открыть другой "документ" , в то время как текущий является несохраненным, все, что вы можете сделать, - это выводить сообщение, информирующее пользователя об их выборе, либо закрыть текущий "документ" , либо отказаться от его изменений, либо выбрать сохранение. Пользователю придется выполнить эти действия вручную, а затем снова выбрать "документ" .

Возможно, вы сможете немного улучшить ситуацию, если ваше приложение поддерживает несколько "открытых" документов, по крайней мере, пользователь не будет облагаться налогом за открытие "документа".

Ответ 2

Короткий ответ на ваш вопрос: "НЕТ" , потому что второй Dialog больше не инициирован пользователем для среды выполнения silverlight. То же самое верно, если вы открываете MessageBox перед открытием диалога.

Вот информация из MSDN об ограничениях безопасности в диалогах

В целях безопасности, если приложение 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();
}

Когда вы действительно быстро нажимаете "Enter" -Key, когда отображается MessageBox, после этого открывается окно OpenFileDialog, не создавая исключения безопасности. Но если вы оставите MessageBox открытым в течение небольшого промежутка времени, после закрытия MessageBox возникает исключение SecurityException.

Я думаю, что ограничение по времени - это проблема, показывающая два диалога один за другим, потому что предел времени будет превышать первый.

Ответ 3

Вы должны показывать SaveFileDialog в обработчике мыши Click. В вашем случае это будет в private void b_Click.

Помещение некоторых препятствий между щелчком мыши и SaveFileDialog не будет работать.