简体   繁体   English

在WPF MVVM中从一个视图导航到另一个视图

[英]Navigation from one view to another in WPF MVVM

I wrote code which should navigate between user controls in WPF application using MVVM, but I realised that this code doesn't work. 我编写了应使用MVVM在WPF应用程序中的用户控件之间导航的代码,但我意识到该代码不起作用。 From window LoginView I want to change the view to VotingCardView . 从窗口LoginView我想将视图更改为VotingCardView

Actually, after clicking on the button in the LoginView , the method DisplayVCV gets executed, but the view is not going to change. 实际上,单击LoginView的按钮后,将执行DisplayVCV方法,但是视图不会改变。 What am I doing wrong? 我究竟做错了什么?

MainView.xaml: MainView.xaml:

<Window x:Class="ElectionCalculator.View.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ElectionCalculator"
        xmlns:v="clr-namespace:ElectionCalculator.View"
        xmlns:vm="clr-namespace:ElectionCalculator.ViewModel"
        mc:Ignorable="d"
        Title="Election calculator" Height="350" Width="525">
    <Window.DataContext>
        <vm:MainViewModel />
    </Window.DataContext>
    <ContentControl Content="{Binding ViewModel}" />
</Window>

LoginView.xaml: LoginView.xaml:

<UserControl x:Class="ElectionCalculator.View.LoginView"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:ElectionCalculator.View"
      xmlns:vm="clr-namespace:ElectionCalculator.ViewModel"

      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300">

    <Grid>
        <Button Command="{Binding DataContext.DisplayVC, RelativeSource={RelativeSource AncestorType={x:Type Window}}, Mode=OneWay}" Margin="161,147,47,124" />
    </Grid>

</UserControl>

MainViewModel.cs MainViewModel.cs

class MainViewModel : BaseViewModel
{
    public BaseViewModel ViewModel { get; set; }

    public MainViewModel()
    {
        ViewModel = new LoginViewModel();
    }

    public ICommand DisplayVC { get { return new RelayCommand(DisplayVCV); } }

    public void DisplayVCV()
    {
        ViewModel = new VotingCardViewModel();

        MessageBox.Show("DisplayVCCommandExecuted");
    }
}

Your ViewModel property implementation doesn't raise a PropertyChanged event when the value changes. 当值更改时,您的ViewModel属性实现不会引发PropertyChanged事件。 This is usually done via an INotifyPropertyChanged implementation. 这通常通过INotifyPropertyChanged实现来完成。 Because of that, your view doesn't get notified that something has changed. 因此,您的视图不会收到有关某些更改的通知。

In your case, this means that you need a backing field for your ViewModel property and implement your ViewModel property similar to this: 在您的情况下,这意味着您需要为ViewModel属性提供一个后备字段并实现类似于以下内容的ViewModel属性:

private BaseViewModel _viewModel;
public BaseViewModel ViewModel
{
  get { return _viewModel; }
  set
  {
    if(_viewModel != value) 
    {
      _viewModel = value;
      OnPropertyChanged("ViewModel");
    }
  }
}

Since you are already deriving from BaseViewModel I assume that the method OnPropertyChanged (or some method with a similar name) is implemented there. 因为您已经从BaseViewModel派生了,所以我假设在那里实现了方法OnPropertyChanged (或一些名称相似的方法)。 It is also quite common that you don't have to specify the property name ( "ViewModel" ) as an argument, since lots of implementations use the [CallerMemberName] attribute for this purpose. 不必指定属性名称( "ViewModel" )作为参数也是很常见的,因为许多实现为此目的都使用[CallerMemberName]属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM