2013-02-17 58 views
0

我正在使用caliburn micro。我的問題是如何管理對話框。 最大的問題是,因爲當不使用窗口時,你的代碼不會停下來等待。MVVM多個對話框令人頭疼

所以我做了這樣的事情。

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

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

} 

這有很多problem.For例子的情況下,我想顯示一個對話框,然後在回調我想表明在某些情況下,對話框早餐的旅館而來的疑難問題都來寫的DoSomething額外功能爲了不duplicate.And我失去所有其他本地variables..The問題較大時需要更多的水平..

showDialog(A, (cb)=>{ 

    if(...) { 

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

    }); 

    } 
    else{ 
    DoSomething(); 
    } 
}); 

還因爲我想一次顯示我延長Collection.OneActive一個對話框。但是這也有問題。在停用事件回調時,如果我想要,我無法關閉所有事件!因爲它在內存中保留下一個參考後禁用觸發,即使你清除它再次來..

回答

1

如何使用類跟蹤狀態信息,當你在對話框之間移動,而不是像你所示的嵌套閉包原始的例子?

我認爲你是在正確的軌道上,但似乎你有兩個問題:

  1. 你做的嵌套的量,不利於代碼清晰。
  2. 您需要更好的方法來捕獲對話框之間的局部變量和狀態信息。

要解決第一個問題,我建議將您的邏輯分解爲不同的方法。每次停用對話框時,都可以有一個方法來處理之後應該執行的邏輯。

要解決第二個問題,您可以嘗試創建一個負責存儲要在對話框之間傳遞的信息的類。這個類的一個實例可以作爲參數傳遞給每個要在對話停用時執行的方法。

這裏是你如何能做到這一點:

指揮類

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. 
    } 
} 

對話情境類

在這裏你將存儲之間需要傳遞的狀態信息對話框。我只在此列舉了一處房產作爲示例,但您可以在此處輸入很多信息。

/// <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 2013-02-17 20:51:34

+0

唯一可行的解​​決方法是不使用TryClose,但(this.Parent作爲DialogConductorViewModel).DeactivateItem(this,false); – GorillaApe 2013-02-17 20:53:38