在WPF中切换屏幕

3
我刚开始使用WPF,想了解在使用MVVM Light Toolkit的WPF应用程序中跨多个屏幕导航时人们推荐的最佳实践。由于我是WPF的新手,请原谅我的术语可能不正确,因为我不确定正确的术语是“切换视图”,“导航页面”,“更改窗口”还是其他什么(有关这些术语与WPF相关的澄清将不胜感激)。
为了澄清我的意思:我有一个应用程序,其中有3个全屏页面/视图,用户应该能够在它们之间来回移动。这些视图永远不会同时显示,因此它们最容易与选项卡控件中的选项卡进行比较;但是我不想要通常带有选项卡控件的选项卡条。相反,我想以编程方式在页面/视图之间切换。
我在以下stackoverflow答案中看到了一些不同的方法:
  1. https://dev59.com/cG025IYBdhLWcg3wRDq8#6114865
  2. How to navigate through windows with MVVM Light for WPF?
我想知道上述两种方法哪一种是我应该采用的方向?实际上,我已经实现了第一个答案,但我不确定这是否是对数据模板的“滥用”或“黑客攻击”,或者这是否是框架的正确使用方式。
最后,也许MVVM Light并不是我应该使用的最合适的工具包,如果其他工具包可以直接提供此功能,有人能否解释一下这个概念,并推荐一个更适合的工具包?
谢谢。

1
这实际上正是 WPF 的工作原理 :) 你的应用程序由你创建的对象(ViewModels/Models)组成,你使用 DataTemplates 和 UI 对象告诉 WPF 如何绘制你的应用程序。这与 WinForms 相反,你在 WinForms 中通过构建 UI 对象来构建应用程序,并提供所需的数据。 - Rachel
那么,我所引用的第二个答案的导航设施究竟是用来做什么的? - David Gutierrez
我以前没有使用过那段代码,但它似乎是一个能够完成相同任务的框架。你将一个对象设置为“当前”页面,然后它使用ViewModelLocator来定位正确的视图以绘制该页面。 - Rachel
我明白了,谢谢你的信息。如果您不介意,我还有一个问题:您如何使用您的方法处理过渡效果? - David Gutierrez
我会从视图中处理它们,因为它们是视图特定的功能。我可能会在代码后台附加一个监听器以便在更改时运行一些动画。最简单的方法可能是订阅ViewModel的PropertyChange事件,虽然我相信还有其他方法可以实现,比如使用消息系统。 - Rachel
我明白了,我想我希望有一种内置的方法来完成这个。还有一个问题(如果您不介意的话,再次感谢您的帮助):您将数据模板存放在哪里,以便您可以在设计时在Visual Studio中编辑和查看它们?目前,当它们位于资源字典中时,Visual Studio无法呈现我的数据模板。 - David Gutierrez
2个回答

1
一个快速而简单的导航示例(此处是手写的,而不是在VS中编写的,因此如果有拼写错误,请进行修正):
让我们创建一个视图的分层描述:
  public abstract Class ViewModelBase : INotifyPropertyChanged{} 
  public abstract Class ViewModelNavigationBase : ViewModelBase {} 
  public Class ViewModel1 : ViewModelNavigationBase {}
  public Class ViewModel2 : ViewModelNavigationBase {}
  public Class ViewModel3 : ViewModelNavigationBase {}

  public Class MainViewModel : ViewModelBase 
  {
      private ViewModelNavigationBase  currentViewModel; 
      public ViewModelNavigationBase  CurrentViewModel 
      {
         get{return currentViewModel;}
         set
         {
            currentViewModel = value;
            OnPropertyChanged("CurrentViewModel");                
         }
      }          

      private const int numberOfPages = 3 ;
      private int index;
      private ViewModelNavigationBase[numberOfPages] pages;
      ....
      ... OnNavigateCommand()
      {
          index++;
          index = index % numberOfPages;
          CurrentViewModel = pages[index];
      }

 }

资源:

     <local:MainViewModel x:Key="MainVm" /> 

     <DataTemplate TargetType={x:Type local:ViewModel1}>
         <local:View1 />
     </DataTemplate>

     <DataTemplate TargetType={x:Type local:ViewModel2}>
         <local:View2 />
     </DataTemplate>

     <DataTemplate TargetType={x:Type local:ViewModel3}>
         <local:View3 />
     </DataTemplate>

xaml:

 <Window x:Name="MainWindow" 
         DataContext={StaticResource MainVm}>
       <StackPanel>
           <ContentControl Content={Binding CurrentViewModel} />
           <Button Content="Navigate" Command="{Binding NavigateCommand}"/>
       </StackPanel>       
 </Window>     

谢谢,我已经按照我链接的第一个答案实现了这个功能。我想知道为什么这比第二个答案更受欢迎,哪个是正确的方法。 - David Gutierrez
在MVVM Light工具包上,您使用了一个不属于WPF框架的第三方库, 我认为在框架之上实现更有益,因为您可以维护自己的代码,并且您可以更清楚地了解框架的工作原理。 - eran otzap

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接