Показать одну дочернюю виртуальную машину, затем показать другую после закрытия первой

У меня есть один родительский проводник. Я хочу показать первую модель просмотра внутри нее. Затем, после закрытия первого (т.е. выполнения некоторой операции), я хочу показать другую модель представления.

Я использую Caliburn.Micro.Contrib, где ConductResult отображает дочернюю ВМ в Conductor. У него есть классный метод расширения AfterClosingDo, который запускает сопрограмму после деактивации и закрытия дочернего элемента.

Однако, когда я запускаю другой ConductResult, используя AfterClosingDo, в основном это происходит:

  • первая дочерняя виртуальная машина закрыта
  • Происходит деактивированное событие, ConductResult запускает действие AfterClosing
  • в AfterClosing я открываю вторую дочернюю виртуальную машину, используя ConductResult в родительском проводнике
  • вторая дочерняя виртуальная машина правильно активирована
  • однако деактивация первой дочерней ВМ еще не завершена, а элемент null установлен как активный в проводнике

Первая виртуальная машина в основном показывает ход операции загрузки, вторая виртуальная машина показывает фактические данные. После завершения загрузки я хочу показать данные в родительском проводнике (конечно, используя вторую виртуальную машину).

Итак, мой вопрос: есть ли чистый способ сделать это в Caliburn.Micro, предпочтительно, не переопределяя поведение проводника, экрана и т. д. по умолчанию.

Я думал об использовании EventAggregator, хотя не уверен, что это лучшее решение.


person mnn    schedule 17.03.2013    source источник


Ответы (1)


У меня была очень похожая проблема, когда у меня был проводник, открывающий дочернюю виртуальную машину, затем появлялось окно подтверждения с надписью «Вы хотите закрыть» и запускался обратный вызов для метода исходных элементов CanClose, который имел такой же эффект. как вы описали.

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

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

  • Открыть ВМ 1
  • Попробуйте закрыть ВМ 1
  • Сработал защитный метод CanClose
  • Всплывающая ВМ 2 (с использованием того же проводника) в CanClose ВМ 1
  • Кнопка подтверждения на виртуальной машине 2 нажата
  • Кнопка подтверждения запускает обратный вызов для CanClose и закрывает VM1
  • ВМ2 закрывается
  • Проводник запоминает, что ВМ 1 была активна до ВМ 2, поэтому повторно открывает ВМ 1 после ее закрытия.

В конце концов я просто реализовал интерфейс, который срабатывал после закрытия.

Дочерние элементы, у которых есть работа после закрытия, реализуют интерфейс (IAfterClose)

Затем я предоставил переопределение для DeactivateItem в проводнике:

    public override void DeactivateItem(IScreen item, bool close)
    {
        var afterClose = item as IAfterClose;

        base.DeactivateItem(item, close);

        if (afterClose != null && close)
            afterClose.AfterClose();
    }

Это гарантировало, что обратный вызов не будет запущен слишком рано. Не уверен, что это принесет вам пользу (поскольку я не использовал библиотеку contrib), но это может дать вам некоторые идеи.

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

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

person Charleh    schedule 17.03.2013
comment
Если вам интересно, я, наверное, знаю, почему в DefaultCloseStrategy.Execute() возникает исключение нулевой ссылки. Я не уверен, является ли это ошибкой или каким-то неправильным использованием фреймворка, но я зарегистрировал проблему: caliburnmicro.codeplex.com/workitem/301 - person mnn; 31.03.2013
comment
Круто, я немного изучил это и увидел, где была выброшена нулевая ссылка, но не пошел дальше этого, поскольку в то время у меня не было исходного кода / pdbs CM - надеюсь, это будет исправлено командой CM. Спасибо за информацию! - person Charleh; 01.04.2013