Caliburn.Micro 的导航和生命周期管理
Caliburn.Micro 提供了一套强大的导航和生命周期管理机制,尤其适用于 MVVM 模式的应用程序。在 WPF 或 UWP 等平台上,视图的导航、创建、销毁以及状态管理都是关键问题。Caliburn.Micro 提供了自动化处理这些任务的能力。
1. NavigationService
在 Caliburn.Micro 中,导航主要通过 INavigationService 接口完成。这个接口封装了导航的基本操作,例如 NavigateToViewModel
、GoBack
和 GoForward
等,适用于不同平台的页面导航。
关键方法:
INavigationService.NavigateToViewModel<T>()
:导航到指定的 ViewModel。INavigationService.GoBack()
:返回上一个页面。INavigationService.GoForward()
:前进到下一个页面。INavigationService.CanGoBack
:判断是否可以返回。INavigationService.CanGoForward
:判断是否可以前进。
示例:
public class ShellViewModel : Conductor<object>
{
private readonly INavigationService _navigationService;
public ShellViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
public void NavigateToHome()
{
_navigationService.NavigateToViewModel<HomeViewModel>();
}
public void GoBack()
{
if (_navigationService.CanGoBack)
{
_navigationService.GoBack();
}
}
}
2. Conductor 和 Screen 的生命周期管理
Conductor 和 Screen 是 Caliburn.Micro 的两个核心类型,用于管理 ViewModel 的生命周期和激活/取消激活(activation/deactivation)过程。
- Conductor:负责管理一组子 ViewModel,控制它们的激活和取消激活。这是实现导航和内容切换的重要类型。
- Screen:表示一个可以显示的页面或模块。它有自动的生命周期管理,主要方法包括
Activate
和Deactivate
,Caliburn.Micro 会根据视图模型的状态自动调用这些方法。
生命周期的关键方法:
- OnActivate():在视图模型被激活时调用。
- OnDeactivate(bool close):当视图模型被取消激活或关闭时调用。
close
参数表示是否关闭。 - CanClose():在关闭时,允许你控制是否允许关闭该视图模型。
2.1 Conductor 的使用示例
public class ShellViewModel : Conductor<object>
{
public void OpenHomePage()
{
ActivateItem(new HomeViewModel());
}
public void OpenSettingsPage()
{
ActivateItem(new SettingsViewModel());
}
public void CloseCurrentPage()
{
DeactivateItem(ActiveItem, close: true);
}
}
2.2 Screen 的使用示例
public class HomeViewModel : Screen
{
protected override void OnActivate()
{
base.OnActivate();
// 页面加载时执行的逻辑
Console.WriteLine("HomeViewModel Activated");
}
protected override void OnDeactivate(bool close)
{
base.OnDeactivate(close);
// 页面关闭或取消激活时执行的逻辑
Console.WriteLine("HomeViewModel Deactivated");
}
}
3. 多种导航场景的支持
Conductor 有三种模式来管理多个子 ViewModel:
- Conductor with Collection.AllActive:允许多个 ViewModel 同时处于激活状态,常用于多文档界面(MDI)。
- Conductor with Collection.OneActive:一次只允许一个 ViewModel 处于激活状态,常用于典型的主从视图(Master-Detail)或导航模式。
- Conductor without Collection:处理单一激活的对象,通常用于简单的导航场景。
示例:Collection.OneActive 模式
public class ShellViewModel : Conductor<Screen>.Collection.OneActive
{
public ShellViewModel()
{
Items.Add(new HomeViewModel());
Items.Add(new SettingsViewModel());
// 激活第一个视图模型
ActivateItem(Items.First());
}
public void NavigateTo(int index)
{
ActivateItem(Items[index]);
}
}
4. IDeactivate 和 IActivate 接口
IDeactivate 和 IActivate 接口用于手动管理对象的激活和取消激活状态。它们允许你精确控制生命周期管理,通常用于复杂的视图导航逻辑。
- IActivate:定义了一个 Activated 事件和一个 Activate() 方法,用于手动触发激活。
- IDeactivate:定义了一个 Deactivated 事件和一个 Deactivate() 方法,可以选择是否永久关闭。
5. ViewModel 的导航状态持久化
对于需要在页面导航时保留状态的场景,你可以使用 INavigationService 提供的状态管理方法,如 State
属性,配合序列化/反序列化保存导航状态。
public class MyViewModel : Screen
{
private readonly INavigationService _navigationService;
public MyViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
public void SaveState()
{
_navigationService.State["SomeData"] = "Important State";
}
public void LoadState()
{
if (_navigationService.State.ContainsKey("SomeData"))
{
var state = _navigationService.State["SomeData"];
// 加载保存的状态
}
}
}
6. 总结
Caliburn.Micro 提供了高度集成的导航和生命周期管理功能,包括通过 INavigationService 实现的导航、通过 Conductor 和 Screen 实现的 ViewModel 管理、以及对激活和取消激活的全面支持。这些特性让 MVVM 应用的导航逻辑更加简洁、优雅且易于扩展。
7. 扩展
- 你可以结合 IoC 容器 与 Conductor 实现复杂的模块化导航和视图管理。
- 通过继承 Conductor 并实现自定义激活/取消激活逻辑,可以进一步灵活控制页面导航行为。