我知道有很多关于WPF导航的问题,对于使用MVVM模式开发的应用程序,我已经阅读了数十个答案,但我可能遗漏了一些东西。 我开始根据Rachel的文章here构建一个应用程序。一切正常,这个XAML有一个 ApplicationView 窗口:
<Window x:Class="CashFlow.ApplicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:CashFlow.ViewModels"
xmlns:v="clr-namespace:CashFlow.Views"
Title="ApplicationView" Height="350" Width="600" WindowStartupLocation="CenterScreen">
<Window.Resources>
<!--Here the associations between ViewModels and Views-->
<DataTemplate DataType="{x:Type vm:HomeViewModel}">
<v:HomeView />
</DataTemplate>
</Window.Resources>
<!--Define here the application UI structure-->
<DockPanel>
<Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
<ItemsControl ItemsSource="{Binding PageViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding}"
Margin="2,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
<ContentControl Content="{Binding CurrentPageViewModel}" />
</DockPanel>
ApplicationViewModel ,在应用程序启动时为此窗口设置为 DataContext ,维护我的ViewModel的 ObservableCollection 。借助数据模板,可以使用 ContentControl 来渲染视图,从而将每个视图与其视图模型相关联。在这种情况下导航是通过&#34;侧栏&#34;按钮,绑定到执行 CurrentPageViewModel 对象更改的 ApplicationViewModel 命令。 我想知道如果没有按钮的侧边栏我可以执行导航。只有 Content 控件,我应该能够从其他viewmodel更改 CurrentPageViewModel 吗?可能答案非常简单,但我现在无法看到。
答案 0 :(得分:1)
您的顶级homeview模型可以通过eventbus模式编排导航。要使用eventbus,您将注入一个跟踪想要通知事件的对象的对象。然后,当视图模型引发事件时,homeviewmodel会接收它并执行currentpageviewmodel分配,该分配将导航到下一个视图模型。
例如:
Messenger
定义了两种方法 - RegisterForEvent<IEvent>(ViewModel aViewModel)
和RaiseEvent(IEvent event)
。
所以你要定义一个订阅事件的函数 -
HomeViewModel.cs
...
void SubscribeForEvents() {
Messenger.RegisterForEvent<NavigationEvent>(this);
}
然后将Messenger注入其他视图模型,并从这些视图模型中引发事件:
Messenger.RaiseEvent(new NavigationEvent { TargetViewModel = new TargetViewModel() });
事件类似于
public class NavigationEvent : IEvent {
ViewModel TargetViewModel { get;set;}
}
答案 1 :(得分:0)
C鲍尔对你所缺少的是正确的。我发现为了切换数据上下文,你需要一个信使服务来标记你的“applicationviewmodel”来切换它的数据上下文。在讨论中here详细讨论了您需要的步骤。
在applicationviewmodel中注册要接收的消息,然后在接收消息功能中处理数据上下文切换。
此外,这可能是真的,但我不得不使用1个窗口,如果我想要始终显示1个窗口,则使用多个用户控件而不是多个窗口。最后,我跟着Sheridan's example并在我的app.xaml中定义了我的数据模板,而不是窗口本身。