2013-02-17 2 views
0

Я использую микрофон caliburn. Моя проблема заключается в том, как управлять диалоговыми окнами. Самая большая проблема в том, что, поскольку, когда вы не используете окно, ваш код не останавливается и не ждет.MVVM множественные диалоги головная боль

Так что я сделал что-то вроде этого.

public void ShowDialog(IScreen dialogModel, Action<object> callback = null) 
{ 
    ActivateItem(dialogModel); 

    if (callback != null) 
     dialogModel.Deactivated += delegate { callback(dialogModel); }; 

} 

Это много, например problem.For в случае, если я хочу, чтобы показать диалог, а затем в обратном вызове я хочу, чтобы показать диалоговое окно B в определенных случаях наступает problem.I должны написать дополнительные функции для DoSomething чтобы не duplicate.And я потерять все другие местные проблемы variables..The больше, когда больше уровней требуется ..

showDialog(A, (cb)=>{ 

    if(...) { 

    showDialog(B,(cb2)=>{ 
     DoSomething(); 

    }); 

    } 
    else{ 
    DoSomething(); 
    } 
}); 

также потому, что я хотел показать один диалог в то время я расширенной Collection.OneActive , Но это тоже проблема. В деактивировать обратный вызов события я не мог закрыть все, если бы захотел! Поскольку в памяти сохраняется следующая ссылка после деактивации, и даже если вы ее очистите, она снова появляется.

ответ

1

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

Я думаю, что вы на правильном пути, но мне кажется, что у вас есть две проблемы:

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

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

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

Вот как вы могли бы сделать это:

Conductor Класс

public class DialogTestsViewModel : Conductor<object>.Collection.OneActive 
{ 
    /// <summary> 
    /// Shows a dialog and executes its callback if necessary. 
    /// </summary> 
    /// <param name="dialogModel">The dialog view model to be shown.</param> 
    /// <param name="callback">The callback to be executed when dialog is closed.</param> 
    public void ShowDialog(IScreen dialogModel, Action callback = null) 
    { 
     // Show the dialog. 
     ActivateItem(dialogModel); 

     // If there is a callback, call it when dialog is closed/deactivated. 
     if (callback == null) return; 
     dialogModel.Deactivated += (sender, args) => callback(); 
    } 

    /// <summary> 
    /// This method kicks off the dialog chain. 
    /// </summary> 
    public void ShowFirstDialog() 
    { 
     // Create a new context. This will hold state information 
     // as it is passed between dialogs. 
     var context = new TestDialogContext(); 

     // Create the first dialog's view model. 
     var viewModel = new FirstDialogViewModel(); 

     // Show the first dialog. 
     ShowDialog(viewModel,() => OnFirstDialogDeactivated(viewModel, context)); 
    } 

    /// <summary> 
    /// Logic to be executed when the first dialog is closed. 
    /// </summary> 
    /// <param name="viewModel">The first dialog's view model.</param> 
    /// <param name="context">The state information.</param> 
    private void OnFirstDialogDeactivated(FirstDialogViewModel viewModel, TestDialogContext context) 
    { 
     // Check the view model here and store state information inside the context. 
     if (viewModel.SomethingIsChecked) 
     { 
      context.ShouldShowSecondDialog = true; 
     } 

     // Use information in the view model or the context to decide if we should show the next dialog. 
     // You could also make a decision about which dialog to show next here. 
     if (context.ShouldShowSecondDialog) 
     { 
      var secondDialog = new SecondDialogViewModel(); 
      ShowDialog(secondDialog,() => OnSecondDialogDeactivated(context)); 
     } 
    } 

    /// <summary> 
    /// Logic to be executed when the second dialog is closed. 
    /// </summary> 
    /// <param name="context">The state information.</param> 
    private void OnSecondDialogDeactivated(TestDialogContext context) 
    { 
     // Do more stuff. 
    } 
} 

Dialog Class Контекст

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

/// <summary> 
/// State information to be passed between dialogs. 
/// </summary> 
public class TestDialogContext 
{ 
    public bool ShouldShowSecondDialog { get; set; } 
} 
+0

Спасибо за ваши предложения! Я попытаюсь написать все свои дела, используя ваше предложение, и придумать ответ. Но небольшая проблема, которая, может быть, мне нужна. Позволяет сказать, что я показываю диалог для оплаты, а затем я решаю, что мне нужно второе диалоговое окно. Пока все в порядке. Но в случае, если я покажу второй диалог для пароля, тогда как я могу отключить ВСЕ экраны? http://stackoverflow.com/questions/14896149/caliburn-micro-conductor-problems здесь у меня возникла проблема, потому что после деактивации CM сохраняет ссылку на следующую viewModel, и даже если вы очистите и закроете все, она добавит ее снова. – GorillaApe

+0

только обходной путь, который работал, заключался в том, чтобы не использовать TryClose, но (this.Parent как DialogConductorViewModel) .DeactivateItem (это, false); – GorillaApe

Смежные вопросы