我正在使用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。但这也有问题。在停用事件回调中,如果我想,我无法关闭所有内容!因为它会在触发Deactivated后保留在内存中的下一个引用,即使你清除它也会再次出现..
答案 0 :(得分:1)
如何在对话框之间移动时使用类来跟踪状态信息,而不是如原始示例中所示嵌套闭包?
我认为你走在正确的轨道上,但看起来你有两个问题:
为了解决第一个问题,我建议将你的逻辑分解为不同的方法。每次禁用对话框时,您都可以使用一种方法来处理之后应该执行的逻辑。
要解决第二个问题,您可以尝试创建一个类,该类负责存储您希望在对话框之间传递的信息。可以将此类的实例作为参数传递到将在对话框停用时执行的每个方法。
以下是你如何做到这一点:
指挥类
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; }
}