使用 MVVM 的 WPF 导航

Posted

技术标签:

【中文标题】使用 MVVM 的 WPF 导航【英文标题】:WPF Navigation using MVVM 【发布时间】:2015-08-31 05:18:26 【问题描述】:

我正在尝试关注provided in this post 的答案,但我一定遗漏了一些微不足道的东西。我将DataTemplates 定义为App.xaml,如下所示:

<Application.Resources>
    <DataTemplate DataType="x:Type vm:BlowerViewModel">
        <v:BlowerView />
    </DataTemplate>
    <DataTemplate DataType="x:Type vm:HomeViewModel">
        <v:HomeView />
    </DataTemplate>
</Application.Resources>

然后,在我的MainWindow.xaml 中,我定义了以下代码:

<Window x:Class="App.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:App.UI.ViewModel"
        Title="MainWindow" SizeToContent="WidthAndHeight">
    <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>
    <ContentControl Content="Binding CurrentView" />
</Window>

MainViewModel 的代码包含一个属性CurrentView 和一个ICommand,因此我可以切换视图。定义如下:

public class MainViewModel : BaseViewModel

    private BaseViewModel _currentView;

    public MainViewModel()
    
        CurrentView = new HomeViewModel();
    

    public BaseViewModel CurrentView
    
        get  return _currentView; 
        set
        
            if (_currentView != value)
            
                _currentView = value;
                RaiseChangedEvent("CurrentView");
            
        
    

    public ICommand SwitchView  
        get 
            return new CommandHandler(() => SwitchBlower());
        
    

    protected void SwitchBlower()
    
        CurrentView = new BlowerViewModel(); 
    

在我的HomeView.xaml 中,我定义了一个链接到MainViewModel 的按钮来执行SwitchView ICommand。如下所示。

<UserControl x:Class="App.UI.View.HomeView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:App.UI.ViewModel"
        Height="300" Width="300">
    <Grid>
        <TextBlock>This is the homeview</TextBlock>
        <Button Command="Binding DataContext.SwitchView, RelativeSource=RelativeSource AncestorType=x:Type vm:MainViewModel, Mode=OneWay" Content="Test" />
    </Grid>
</UserControl>

当我启动应用程序时,它不会注册事件,并且单击按钮不会触发事件以更改视图。我尝试在ICommand get 和函数调用本身中都设置断点。起初,我想也许我需要在我的数据模板中定义MainViewModel,但这样做会导致以下错误(即使项目构建良好)

不能在样式中放置一个窗口

谁能提供我需要的缺失部分来完成这项工作?

【问题讨论】:

AncestorType 应该是 MainWindow 而不是 MainViewModel。 MainViewModel 不是可视化树的一部分。粗略一看,其他一切都很好。 @LeeO。如果您想将其发布为答案,我很乐意将其标记为已接受。看起来这对我来说是一个隧道视野的案例!非常感谢。 现在看来你们都整理好了,干得好。 【参考方案1】:

AncestorType 应该是 MainWindow 而不是 MainViewModel。 MainViewModel 不是可视化树的一部分。

【讨论】:

以上是关于使用 MVVM 的 WPF 导航的主要内容,如果未能解决你的问题,请参考以下文章

.NET Core 3 WPF MVVM框架 Prism系列之导航系统

如何使用 MVVM Light for WPF 在窗口中导航?

WPF、MVVM、导航、保持依赖注入完整

WPF MVVM 在按钮单击时在视图之间导航

在 WPF MVVM 中的视图之间导航

关于使用 Caliburn.Micro MVVM WPF 进行视图导航的建议