【问题标题】:Hierarhical navigational model with Caliburn.Micro使用 Caliburn.Micro 的分层导航模型
【发布时间】:2026-02-05 17:00:02
【问题描述】:

我想在 WPF MVVM 应用程序中实现以下分层导航模型:

ShellView
    Page1View
       Subpage1View
           Subpage2View
       Subpage3View
    Page2View
        ...

这意味着在 Shellview 上,我有激活/停用 Page1View 和 Page2View 的按钮。在 Page1View 上有激活 Subpage1View 和 Subpage3View 的按钮,而 Subpage1View 有一个激活 Subpage2View 的按钮。

子页面应该在哪里显示?导航模型是否应该准确地映射到视图结构?我的意思是,我在 ShellView 上有一个 ContentControl(名为 ActiveItem),激活时会在其中显示 Page1View 和 Page2View。 Subpage1View 应该显示在 Shell 的 ActiveItem ContentControl 上还是父视图(Page1View)上?

  1. 如果我应该在 ShellView 上显示一个子页面,那么如何正确激活它?因为激活它的按钮在 Page1View 上而不是在 shell 上。

  2. 如果我应该在父视图 (Page1View) 上显示一个子页面,那么我必须在 Page1View 上创建一个 ActiveItem ContentControl 并在需要之前将其隐藏。如何 ?另外我猜父视图滚动条可能会成为一个问题。

请指教!

使用 Caliburn.Micro 1.3、.NET 4、WPF。

谢谢!

【问题讨论】:

    标签: c# .net wpf silverlight caliburn.micro


    【解决方案1】:

    我一起扔了一个演示。我不确定它是否正是您正在寻找的。要记住的是ScreensConductors 可以包含Screens 和/或Conductors。所以嵌套或进行复杂的屏幕合成非常简单。

    这个例子有一个ShellView,有两个按钮和一个ContentControlPage1ViewModel 也有 2 个按钮和一个 ContentControl

    单击Page1ShellView 上的Page2 按钮可激活相应的Page。激活Page 后也是如此,单击SubPage1SubPage2 会激活相应的SubPage

    https://bitbucket.org/dbeattie/cmwpfnavsample/src

    【讨论】:

    • 是的,谢谢,但问题是我希望 SubPage 填满整个 Page1。在您的示例中,SubPage 仅填充 Page1 上的一个控件,但我希望它填充整个 Page1 屏幕。
    • 啊,它们都可以在一个内容控件中,嵌套页面上的按钮会告诉 shell 使用 EventAggregator 激活不同的视图模型。
    • 不知道我是否理解..你能提供一个例子吗?
    • 我可以,我没有时间,但更改链接以显示这一点并不需要太多。
    • 我还是有问题..如何通过 ViewModel ?
    【解决方案2】:

    我们这样使用子页面:

    • 子页面本身显示在页面视图中的 ContentControl 中。所以我们有一个外壳视图,它有一个 ContentControl 来显示活动页面,在这个活动页面中,还有另一个 ContentControl 来显示活动子页面。
    • 我们在 shell 视图本身上显示当前页面的子页面列表(因为布局),所以我们有绑定到 ActiveItem.Items 的 ItemsControl(假设 ActiveItem 是从 Conductor 继承的页面)。

    所以我们只需使用 ItemsControl 来选择当前活动的页面或子页面,然后使用 ContentControl 来显示它。请注意,选定的子页面通过其父页面视图显示。

    但基本上,您是直接在 shell 视图上显示子页面(ContentControl 绑定到 ActiveItem.ActiveItem)还是使用其他方式,这取决于您。

    虽然不包括子页面,但Coproject 示例应用程序可能会对您有所帮助。我打算让它更复杂,稍后再添加子页面。

    ad 2. 我认为您不需要隐藏 ContentControl - 如果没有选择子页面,它将为空。不过,如果你想隐藏它,我建议使用 ValueConverter(从对象到 Visibility,如果 object == null 然后 Visibility.Collapsed,否则 Visible)并将 ActiveItem ContentControl 的 Visibility 属性再次绑定到 ActiveItem。

    【讨论】: