在Caliburn Micro WinRT 8.1中管理简单状态:导航到以前活动的页面

时间:2014-01-22 15:36:02

标签: c# windows-runtime caliburn.micro

我正在基于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

1 个答案:

答案 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>();
}