MVVM应用程序无法正确恢复状态

时间:2014-09-02 22:09:09

标签: wpf mvvm mef caliburn.micro avalondock

我已经构建了一个类库,它可以作为GUI框架,可以被其他项目继承。此应用程序基于项目WildGemini

我的问题是使用标准序列化器恢复Avalon Dock的布局

var layoutSerializer = new XmlLayoutSerializer(manager);

其中manager的类型为DockingManager。经理恢复并清空标签。我的猜测是Caliburn Micro无法找到存储的ViewModel(名为HomeViewModel)。但是,我正在努力证实这一点。

我相信我的引导程序是正确的,MEF容器正在正确设置以允许解析外部类型。我已经调试了项目,我认为这个问题正在发生,在输出窗口中,我可以看到发生附着的Attach(Home)(注意," Home"是显示名称的HomeViewModel)。但是,我不知道附加过程有什么问题,因为这是由MEF / Caliburn处理的。

我真的很难调试这个想知道的

  1. 任何人都可以就如何进行调试过程提供任何有见地的建议吗?
  2. 任何人都愿意看一下这个解决方案吗?
  3. 我花了很多时间调试这个没有任何运气,这个问题足够深奥和虚幻,以至于这里的大部分帖子都与我无关。

    感谢您的时间。

1 个答案:

答案 0 :(得分:2)

正如所讨论的那样,在查看提供的示例代码之后,我理解以下

  • HomeViewModel或者可以说LayoutItemBase不应该重新打开,因为ShouldReopenOnStartup设置为false
  • 如果您在为HomeViewModel打开文档时关闭应用程序,则会在下次启动时将其恢复为空白视图[Not OK]

<强>分析

SaveState方法正确地表达ShouldReopenOnStartup值并且没有为HomeViewModel发出状态,但是停靠管理器仍在为文档发出元素。

因此,在下次重新启动时,LoadState找不到任何存储状态,但创建了一个窗口,因为停靠管理器布局状态中存在一个元素

  <LayoutDocument Title="HomePP" IsSelected="True" IsLastFocusedDocument="True" ContentId="d716f824-cfff-4b54-8fd6-2d026a99369a" .../>

你确实尝试使用序列化回调的e.Cancel属性来取消事件,但似乎不应该阻止加载窗口,而只是在不需要时取消事件。

解决

所以理想的方法是在保存布局之前关闭不应该恢复的文档

这是我的做法

ShellViewmodel.cs : Line 279方法SaveState(string)

更改以下代码

    if (!item.ShouldReopenOnStartup)
        continue;

    if (!item.ShouldReopenOnStartup)
    {
        //this item is not supposed to be restored so close the window before saving layout
        IDocument doc = item as IDocument;
        if (doc != null)
            CloseDocument(doc);
        continue;
    }