0

我正在使用caliburn micro。我的问题是如何管理对话框。最大的问题是,因为当不使用窗口时,您的代码不会停止并等待。

所以我做了这样的事情。

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

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

}

这有很多问题。例如,如果我想显示对话框 A,然后在回调时我想在某些情况下显示对话框 B,就会出现问题。我必须为 DoSomething 编写一个额外的函数,以免重复。并且我失去了所有其他局部变量..当需要更多级别时问题就更大了..

    showDialog(A, (cb)=>{

    if(...) {

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

    });

    }
    else{
    DoSomething();
    }
});

另外因为我想一次显示一个对话框,所以我扩展了 Collection.OneActive 。但这也有问题。在停用事件回调中,如果我愿意,我无法关闭所有!因为它会在内存中保留触发 Deactivate 后的下一个引用,即使您清除它,它也会再次出现..

4

1 回答 1

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; }
}
于 2013-02-17T20:13:31.307 回答