Реализация настоящего модального диалога в Silverlight 5 - PullRequest
3 голосов
/ 16 марта 2012

Я ищу хороший способ реализовать действительно модальное диалоговое окно в Silverlight 5. Каждый найденный мной пример, который утверждает, что создает модальное диалоговое окно, на самом деле не является модальным в том смысле, что вызывающий код ждет, пока диалоговое окно не будет закрыто.

Я понимаю, что это проблема, потому что мы не можем на самом деле заблокировать поток пользовательского интерфейса, потому что он должен работать, чтобы диалог (ChildWindow) функционировал правильно.Но с добавлением TPL в SL5 и более высоким уровнем принятия Silverlight за последние несколько лет я надеюсь, что кто-то нашел способ обойти это.

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

Наше конкретное экономическое обоснование (логическое или нет) заключается в том, что приложениене требует аутентификации пользователя;однако некоторые функции требуют доступа «Менеджер».Когда к функции обращаются (посредством нажатия кнопки или выбранного пункта меню и т. Д.), И текущий пользователь не является менеджером, мы отображаем диалоговое окно входа в систему.Когда диалог закрывается, мы снова проверяем авторизацию пользователя.Если они не авторизованы, мы показываем приятное сообщение и отклоняем действие.Если они авторизованы, мы продолжаем выполнять действие, которое обычно включает в себя изменение текущего представления на что-то новое, где пользователь может делать все, что ему будет предложено.

1 Ответ

5 голосов
/ 11 апреля 2012

Ради закрытия ...

В результате я получил новый DialogService с поддержкой TPL с такими методами:

public Task<Boolean?> ShowDialog<T>()
    where T : IModalWindow

Метод создает экземпляр диалогового окна.(ChildWindow), присоединяет обработчик к событию Closed и вызывает метод Show.Внутренне он использует TaskCompletionSourceвернуть задание вызывающей стороне.В обработчике закрытых событий DialogResult передается методу TrySetResult () в TaskCompletionSource.

Это позволяет отображать диалоговое окно в типичном асинхронном режиме:

DialogService.ShowDialog<LoginDialog>().ContinueWith(task =>
{
    var result = task.Result;

    if ((result == true) && UserHasPermission())
    {
        // Continue with operation
    }
    else
    {
        // Display unauthorized message
    }
}, TaskScheduler.FromCurrentSynchronizationContext());

Или яможет блокироваться с помощью метода Task.Wait () - хотя это проблематично, потому что, как я упоминал в оригинальном посте, он блокирует поток пользовательского интерфейса, поэтому даже диалоговое окно заморожено.

Все еще не является истинным модальным диалогом, но немного ближе к поведению, которое я ищу.Любые улучшения или предложения по-прежнему приветствуются.

...