Ошибка Caliburn с Show.Busy () и Show.NotBusy () - PullRequest
1 голос
/ 10 марта 2011

У меня есть диалоговое окно, которое отображается с помощью Show.Dialog (), и содержит следующие шаги в методе, присоединенном к событию Loaded представления:

  1. Show.Busy ()
  2. Возможен длительный веб-запрос (у меня здесь пользовательский асинхронный результат)
  3. Всплывающее окно с ошибкой через Show.MessageBox ()
  4. Show.NotBusy ()

Я обнаружил, что если вы закрываете мой вид на шаге 2, когда он занимает некоторое время, и снова открываете, индикатор занятости для шага 1 на новом виде не отображается.

Итак, сначала я подумал, что это моя вина, и добавил простой механизм для отмены шага 4, если представление было закрыто. Но не повезло ...

Как это выглядит, Show.Busy () на шаге 1 пытается взаимодействовать с уже закрытым представлением. Это ошибка в Caliburn?

Моя ViewModel является одноэлементной, так что это также может относиться к проблеме, я полагаю. Для теста я переключился на логическое свойство IsBusy, и проблема исчезла. Однако это будет большим изменением для всего моего приложения.

Мысли о каких-либо обходных решениях? Или один из ребят из Caliburn поможет мне здесь? Я использую последнюю версию полной версии Caliburn.

UPDATE:

Я попробовал обходной путь Марко, импортировал IBusyService и сделал это в моей ViewModel:

public override void TryClose(bool? dialogResult)
{
    _busyService.MarkAsNotBusy(this);

    base.TryClose(dialogResult);
}

Но, похоже, это не помогает. Поможет ли мне сделать простое повторение?

ОБНОВЛЕНИЕ № 2:

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

Оказывается, это связано с тем, что мне приходится напрямую вызывать IWindowManager. Мое приложение частично WinForms с архитектурой плагинов, и мы используем несколько плагинов на основе Caliburn.

Вот пример кода, вызывающего проблему:

    if (_child.IsActive)
    {
        _child.BringToFront();
    }
    else
    {
        _manager.ShowWindow(_child);
    }

Это в обработчике события щелчка элемента меню WinForms NotifyIcon.

_child - это экран, где BringToFront () вызывает метод Activate базового представления (конечно, службой). _manager - это IWindowManager.

Если вы работаете прямо в Caliburn, Show.Dialog () не вызывает проблемы.

Есть идеи об обходном пути? Я не уверен, что это проблема Caliburn, но, возможно, она вызвана прямым использованием IWindowManager.

1 Ответ

2 голосов
/ 11 марта 2011

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

Я должен исследовать немного больше, хотя; Я подал вопрос: http://caliburn.codeplex.com/workitem/8395

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

...