51

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

我尝试了这些东西,但无法使其正常工作。

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

4

4 回答 4

128

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

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

public BaseViewModel ViewModel { get; set; }

当然,与这个快速示例不同,您将属性INotifyPropertyChanged上正确实现接口。现在,我们声明了一些简单的 s 来连接视图和视图模型:App.xamlDataTemplate

<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在应用程序中使用我们的哪个实例,这些DataTemplates 都会告诉框架显示相关视图。我们可以这样显示它们:

<ContentControl Content="{Binding ViewModel}" />

所以我们现在需要做的就是切换到一个新的视图是ViewModel从类中设置属性MainViewModel

ViewModel = new PersonViewModel();

最后,我们如何从其他视图中改变视图?那么有几种可能的方法可以做到这一点,但最简单的方法是将Binding子视图中的 a 直接添加ICommandMainViewModel. 我使用自定义版本的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}" />

而已!享受。

于 2013-10-29T09:53:46.413 回答
8

当我第一次开始使用 MVVM 时,我也在为不同的 MVVM 框架特别是导航部分而苦苦挣扎。因此,我使用我发现的这个小教程,Rachel Lim 创建了。它非常好,解释得很好。

在以下链接中查看它:

希望它对你有帮助:)

于 2013-10-29T09:41:29.260 回答
1

也许这个链接会帮助你。只需将该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使用绑定Window即可。RelativeSource例如

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

在每个视图中,只看到您使用等注释类定义背后的代码[NavigationView("firstview")]

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

于 2013-10-30T09:09:29.277 回答
1
<ContentControl x:Name="K.I.S.S" Content="{Binding ViewModel, Converter={StaticResource ViewLocator}}"/>
于 2016-04-11T02:17:36.443 回答