【问题标题】:WPF Caliburn.Micro/mvvm NavigationWPF Caliburn.Micro/mvvm 导航
【发布时间】:2023-03-07 21:30:02
【问题描述】:

我正在构建一个项目,到目前为止我遇到的最大问题之一是导航。
我一直在寻找 caliburn.micro/mvvm 导航的示例,但它们似乎都很长,我无法真正理解其中的大部分内容(这里是初学者!)。

关于我的项目的一些信息:
我希望有一个外部窗口/外壳,菜单链接/选项卡根据在外壳内部单击的按钮打开页面,并且能够从一个内部打开更改页面。

我目前有:ShellViewModel.cs、MainViewModel.cs、我的模型和我的视图。 现在,我只需要知道如何让 MainViewModel 在启动时加载到 shellviewmodel 中(使用 contentcontrol/frames...),以及如何从一个页面移动到另一个页面。

你也可以只写点,然后给我一些有用的例子,我相信我可以从那里继续。 如果可能,最好对内容进行彻底的解释。

【问题讨论】:

    标签: c# wpf mvvm caliburn.micro


    【解决方案1】:

    在官方文档中阅读Conductors and Screens

    举个简单的例子,您的ShellViewModel 可以是一个活动屏幕的Conductor(即一次只有一个屏幕变为活动/非活动):

    public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
    

    然后您可以将ConductorActiveItem 设置为您希望当前处于活动状态的视图模型实例:

    this.ActivateItem(myMainViewModel);
    

    集合Conductor 类型还提供了一个Items 集合,您可以在实例化新窗口时对其进行填充。这个Items 集合中的视图模型可能是那些当前已停用但尚未关闭的视图模型,您可以如上所述使用ActivateItem 激活它们。通过在ShellView 中使用ItemsControlx:Name="Items",它还可以很容易地创建打开窗口的菜单。

    然后,要创建 ShellView,您可以使用 ContentControl 并将其名称设置为与 ActiveItem 属性相同,然后由 Caliburn.Micro 完成其余的工作:

    <ContentControl x:Name="ActiveItem" />
    

    然后,您可以通过覆盖该类中的 OnActivate/OnDeactivate 来响应您的 MainViewModel 中的激活/停用。

    【讨论】:

    • 好吧,你确实简化了这个想法!例如,当我想添加“向后”/“向前”功能时,我应该使用集合 Conductor 类型吗?另外,如何在单击按钮时转到另一个页面?我只使用命令吗?如果是这样,大多数其他示例中使用的 EventAggerator 在哪里派上用场?
    • 您是使用 Conductor 还是其中的一个集合 Conductors 将取决于您是要关闭上一个/下一个屏幕还是仅停用该屏幕。要转到另一个页面,只需调用 ActivateItem 方法。查看文档页面上的操作,以从视图中调用视图模型上的方法。
    • 谢谢。您能否告诉我如何将当前活动视图更改为另一个视图模型中的另一个视图(例如,从使用 OldVieModel 更改为 NewViewModel。)
    • 由于耦合减少了重用,因此视图模型可能彼此不了解。因此,您可以使用标准的 .net 事件或 CM 事件聚合器来通知 shell 进行视图模型的更改。
    • 创建 ShellViewModel 的静态应用程序范围实例并使用它来访问 ActivateItem 方法会更有用吗?
    【解决方案2】:

    在 ShellView 中,您使用这样的内容控件:

    <ShellView xmlns:cal="http://caliburnproject.org/">
         <StackPanel>
               <Button Content="Show other view" cal:Message.Attach="ShowOtherView" />
               <ContentControl cal:View.Model="{Binding Child}" />
         </StackPanel>
    </ShellView>
    

    ShellViewModel:

    public class ShellViewModel : Screen
    {
         private object Child;
    
         public object Child
         {
               get{ return child; }
               set
               {
                    if(child == value)
                         return;
                    child = value;
                    NotifyOfPropertyChange(() => Child);
               }
         }
    
         public ShellViewModel()
         {
             this.Child = new MainViewModel();
         }
    
         public void ShowOtherView()
         {
               this.Child = new FooViewModel();
         }
    }
    

    所以这是一个非常基本的例子。但是如您所见,您的 ShellView 提供了一个ContentControl,它显示了子视图。这个ContentControl 通过View.Model 绑定到ShellViewModel 中的Child 属性。

    在 ShellView 中,我使用了一个按钮来显示不同的视图,但您也可以使用菜单或类似的东西。

    【讨论】:

    • 为了清楚起见,您应该将您的“子”实例声明为某种基本的“ViewModel”类型,例如“PropertyChangedBase”或“屏幕”...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 2016-07-29
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多