我有一个具有多个视图的WPF应用程序。我想从视图1切换到视图2,然后从那里可以切换到多个视图。因此,我想在视图1上使用一个按钮在同一窗口中加载view2。

我尝试了这些操作,但无法正常工作。


如何使用MVVM Light for WPF在Windows中导航?
https://galasoft.ch/posts/2011/01/navigation-in-a-wp7-application-with-mvvm-light

从第一个链接开始,问题在于我不了解ViewModelLocator代码。它们调用CreateMain();函数,但是在哪里定义了该函数,以及如何从视图内部切换到另一个视图。

评论

@AndrasSebö,在这个场合,我不同意你的看法。尽管我承认这不是一个大问题,但我看到的情况要糟得多,而且我相信用户的需求很明确。

好问题是:如何从视图内部切换视图。

您找到解决此问题的好方法吗?

我最终使用了magellan框架。这是具有大量导航功能的应用程序的绝佳框架。

@ user2499088,请添加答案并接受。如果此问题没有可接受的答案,则不能将该问题的重复项作为重复项关闭。请遵循“有人回答我的问题时该怎么办?”中的指南。答案“被接受”是什么意思?帮助中心的页面。

#1 楼

首先,您不需要任何这些工具包/框架即可实现MVVM。可以这么简单...假设我们有一个MainViewModelPersonViewModelCompanyViewModel,每个都有自己的相关视图,并且每个都扩展了abstract基类BaseViewModel

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

public BaseViewModel ViewModel { get; set; }


当然,您可以d不同于此快速示例,在属性上正确实现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的自定义版本,但是您可以使用任何喜欢的类型,并且我猜您会得到图片:

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


在孩子中查看XAML:

<Button Command="{Binding DataContext.DisplayPersonView, RelativeSource=
    {RelativeSource AncestorType={x:Type MainView}}, Mode=OneWay}" />


就这样!享受。

评论


好吧,如果您使用的是MVVM Light,那么您可能应该坚持使用它们来执行这些操作的任何方法……我的意思是,您不需要使用框架来实现此功能。

–谢里登
13-10-29在10:28

我不确定我是否真的了解您的问题@ ETG87。视图模型类只是扩展BaseViewModel类的类,而视图只是UserControls。

–谢里登
2014年5月15日晚上8:37

Dude,您需要阅读有关WPF XAML的XAML命名空间和命名空间映射的信息...我的视图在AppName.Views命名空间中声明,该命名空间具有映射的XAML命名空间前缀。视图模型在AppName.ViewModels命名空间中声明,因此映射到ViewModels的XAML命名空间前缀。应该没有BaseViewModel命名空间,因为那是一个类,而不是命名空间。

–谢里登
2014年5月15日在9:12

@Sheridan,我在应用程序中执行此操作,但是即使我在代码中创建了ViewModel的新实例,XAML代码也会创建另一个实例。有什么办法可以解决这个问题?我试图切换视图并立即绑定到事件,但是由于XAML创建了新实例,所以我无法实现它。

–科迪
2015年4月9日15:40

@AUSTX_RJL,如果还没有,则应该提出一个新问题。

–谢里登
15年7月28日在18:20

#2 楼

当我刚开始使用MVVM时,我还尝试使用不同的MVVM-framework,尤其是导航部分。因此,我使用Rachel Lim创建的这个小教程。

在以下链接上查看它:


http://rachel53461.wordpress.com/2011/12 / 18 / navigation-with-mvvm-2 /

希望对您有所帮助:)

评论


谢谢,但这不是我的意思。我在另一个应用程序中使用了此示例,但是对于该应用程序,我没有侧面菜单。所以我在view1上有一个按钮,当我单击该按钮时,它必须切换到view2

–user2499088
13-10-29在9:52



#3 楼

也许此链接会为您提供帮助。只需将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"。要针对ContentControlWindow,只需使用RelativeSource绑定。对于例如

meffed:NavigationExtensions.NavigationHost="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=ViewContainer}"

在每个视图中,仅需看到您使用[NavigationView("firstview")]注释类定义背后的代码,依此类推。

它第一次很复杂,但是一旦您理解了这个主意,这将非常容易。

#4 楼

<ContentControl x:Name="K.I.S.S" Content="{Binding ViewModel, Converter={StaticResource ViewLocator}}"/>