WPF MVVM导航视图

时间:2013-10-29 09:30:15

标签: c# wpf mvvm navigation

我有一个包含多个视图的WPF应用程序。我想从视图1到视图2的toswitch,从那里我可以切换到多个视图。所以我想在视图1上有一个按钮,它在同一窗口中加载view2。

我尝试过这些东西,但无法让它发挥作用。

从第一个链接问题是我不理解viewmodellocator代码。他们调用CreateMain();函数但是这里定义了什么,以及如何从视图内部切换到另一个视图。

3 个答案:

答案 0 :(得分:105)

首先,您不需要任何这些工具包/框架来实现MVVM。它可以这么简单......让我们假设我们有一个MainViewModelPersonViewModel和一个CompanyViewModel,每个都有自己的相关视图,每个都扩展{{1}基类abstract

BaseViewModel中,我们可以添加公共属性和/或BaseViewModel实例,并实现ICommand接口。因为它们都扩展了INotifyPropertyChanged类,所以我们可以在BaseViewModel类中拥有可以设置为任何视图模型的属性:

MainViewModel

当然,与这个快速示例不同,您将在 属性上正确实现public BaseViewModel ViewModel { get; set; } 界面。现在在INotifyPropertyChanged中,我们声明了一些简单的App.xaml来将视图与视图模型连接起来:

DataTemplate

现在,无论我们在应用程序中使用其中一个<DataTemplate DataType="{x:Type ViewModels:MainViewModel}"> <Views:MainView /> </DataTemplate> <DataTemplate DataType="{x:Type ViewModels:PersonViewModel}"> <Views:PersonView /> </DataTemplate> <DataTemplate DataType="{x:Type ViewModels:CompanyViewModel}"> <Views:CompanyView /> </DataTemplate> 实例,这些BaseViewModel都会告诉框架显示相关视图。我们可以这样显示它们:

DataTemplate

因此,我们现在需要做的就是切换到新视图是从<ContentControl Content="{Binding ViewModel}" /> 类设置ViewModel属性:

MainViewModel

最后,我们如何从其他视图更改视图?好吧,有几种方法可以做到这一点,但最简单的方法是将子视图中的ViewModel = new PersonViewModel(); 直接添加到Binding中的ICommand。我使用MainViewModel的自定义版本,但您可以使用您喜欢的任何类型,我猜你会得到图片:

RelayComand

在子视图中XAML:

public ICommand DisplayPersonView
{
    get { return new ActionCommand(action => ViewModel = new PersonViewModel(), 
        canExecute => !IsViewModelOfType<Person>()); }
}

就是这样!享受。

答案 1 :(得分:7)

当我第一次使用MVVM时,我也在努力使用不同的MVVM框架,特别是导航部分。因此,我使用我发现的这个小教程,即Rachel Lim创建的。这很好,也很好解释。

请在以下链接上查看:

希望它能帮到你:)。

答案 2 :(得分:1)

也许this链接会对您有所帮助。只需将NavigateTo属性设置为您需要在窗口上显示的视图。

例如,您可以执行类似

的操作
<Window x:Class="MainWindowView" 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:meffed="http:\\www.codeplex.com\MEFedMVVM"
                                 meffed:ViewModelLocator.NonSharedViewModel="YourViewModel"
                                 WindowStartupLocation="CenterScreen">

    <Button meffed:NavigationExtensions.NavigateTo="firstview"
                    meffed:NavigationExtensions.NavigationHost="{Binding ElementName=_viewContainer}"
                    meffed:NavigationExtensions.NavigateOnceLoaded="False"
                    Visibility="Visible" />

    <ContentControl x:Name="_viewContainer" Margin="0,0,0,10" />
<Window>

然后类文件将是

public partial class MainWindowView : Window
{
    public MainWindowView()
    {           
              InitializeComponent();
    }

        public ContentControl ViewContainer { get { return _viewContainer; } }

    }

然后,您可以将每个视图定义为UserControl,然后使用上面给出的链接绑定按钮的meffed:NavigationExtensions.NavigateTo="secondView"。要定位ContentControl的{​​{1}},只需使用Window绑定即可。例如

RelativeSource

在每个视图中,只看到使用meffed:NavigationExtensions.NavigationHost="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=ViewContainer}"注释类定义背后的代码,依此类推。

这是第一次很复杂,但一旦理解了这个想法就很容易了。