我正在基于Caliburn.Micro(alpha2)创建一个WinRT 8.1应用程序,我正在为它实现一个简单的状态管理机制。它所需要的只是为其两页或三页中的每一页保存几个名称/值对,并在恢复时恢复当前页面。所以我使用下面概述的策略;鉴于CM / WinRT似乎没有预定义的机制,因此获得任何社区建议会很有意思,或者这可能对像我这样的RT新手有用。
1)我定义了一个接口(IHaveSimpleState
),由具有一些简单状态的VM实现保存和恢复。状态由字典表示,其中每个值都是一个字符串,表示任何序列化值,接口只有两个方法,一个用于将其状态保存到此字典中,另一个用于从字典中恢复它。我所有的有状态虚拟机(每个都对应一个视图)实现了这一点。
2)在我的 app .cs(源自Caliburn.Application
)中,我创建了一个List<WeakReference<IHaveSimpleState>>
来跟踪需要进行状态管理的所有VM:在{ {1}}覆盖实例化虚拟机(使用CM简单容器)我将每个新生成的实例添加到此列表中实现GetInstance
。
3)对于保存状态:在app IHaveSimpleState
覆盖中,我遍历此列表中的所有VM,并调用他们的OnSuspending
方法来收集有关他们的数据在一个普通的字典中陈述。循环完成后,我得到SaveState
并将这些数据复制到其ApplicationData.Current.LocalSettings
字典中,从而有效地保存它们。
4)恢复状态:在应用Values
覆盖和OnResuming
覆盖中(在后一种情况下,仅当OnActivated
等于args.PreviousExecutionState
,即应用程序未被用户终止或崩溃),我调用Running
方法循环遍历列表中的所有VM并调用其ResumeState
方法来加载状态应用程序数据本地设置。
这一切看起来都很好,我只是错过了一点:什么是恢复当前“页面”的正确位置,即告诉Caliburn导航到活动的视图后面的VM暂停时间?我尝试在LoadState
方法(nr.4)的末尾执行此操作,但它似乎太早了,因为当我尝试导航到VM时,我得到一个异常,告诉我相应的视图不能找到。以下是此方法的相关代码:
ResumeState
答案 0 :(得分:0)
我试过这个并且似乎有效,但我对我的应用程序的健壮性感到有些不安,因为CM for 8.1中的生命周期处理似乎没有明确记录,所以我想得到评论或更正来自社区。首先覆盖PrepareViewFirst
方法:
protected override void PrepareViewFirst(Frame rootFrame)
{
_container.RegisterNavigationService(rootFrame);
}
然后在OnLaunched
覆盖中,在我刚刚调用DisplayRootView<MainView>()
之前,我测试args以检查我们是否从暂停状态恢复,如果是,我导航到之前活动的页面;否则我就像以前一样:
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
bool bResumed = false;
if (args.PreviousExecutionState == ApplicationExecutionState.Suspended)
{
AppSimpleState state = LoadState();
string sType = state.Get(APP_CURRENTVM_KEY);
if (sType != null)
{
INavigationService navigation = IoC.Get<INavigationService>();
Type t = Type.GetType(sType);
Debug.Assert(t != null);
navigation.NavigateToViewModel(t);
bResumed = true;
} //eif
}
if (!bResumed) DisplayRootView<MainView>();
}