C# WPF MVVM 导航视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19654295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:32:49  来源:igfitidea点击:

WPF MVVM navigate views

c#wpfmvvmnavigation

提问by user2499088

I have a WPF application with multiple views. I want to switch from view 1 to view 2 and from there I can switch to multiple views. So I want a button on view 1 that loads view2 in the same window.

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

I tried those things, but can't get it to work.

我试过这些东西,但不能让它工作。

From the first link, the problem is that I don't understand the ViewModelLocator code. They call the CreateMain();function but where is this defined, and how can I switch to another view from inside a view.

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

回答by mskydt86

When i first started wiht MVVM I also struggled with the different MVVM-frameworks and especially the navigation part. Therefore I use this little tutorial i found, that Rachel Lim has created. It's very nice and well explained.

当我第一次开始使用 MVVM 时,我也遇到了不同的 MVVM 框架,尤其是导航部分。因此,我使用了我发现的这个小教程,它是 Rachel Lim 创建的。它非常好并且解释得很好。

Have a look at it on the following link:

在以下链接中查看它:

Hope it helped you :)

希望对你有帮助:)

回答by Sheridan

Firstly, you don't need any of those toolkits/frameworks to implement MVVM. It can be as simple as this... let's assume that we have a MainViewModel, and PersonViewModeland a CompanyViewModel, each with their own related view and each extending an abstractbase class BaseViewModel.

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

In BaseViewModel, we can add common properties and/or ICommandinstances and implement the INotifyPropertyChangedinterface. As they all extend the BaseViewModelclass, we can have this property in the MainViewModelclass that can be set to any of our view models:

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

public BaseViewModel ViewModel { get; set; }

Of course, you'd be implementing the INotifyPropertyChangedinterface correctly on yourproperties unlike this quick example. Now in App.xaml, we declare some simple DataTemplates to connect the views with the view models:

当然,你会实现INotifyPropertyChanged上正确接口不像这个简单的例子性能。现在App.xaml,我们声明一些简单的DataTemplates 来连接视图和视图模型:

<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>

Now, wherever we use one of our BaseViewModelinstances in our application, these DataTemplates will tell the framework to display the related view instead. We can display them like this:

现在,无论我们BaseViewModel在应用程序中使用我们的哪个实例之一,这些DataTemplates 都会告诉框架显示相关的视图。我们可以像这样显示它们:

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

So all we need to do now to switch to a new view is to set the ViewModelproperty from the MainViewModelclass:

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

ViewModel = new PersonViewModel();

Finally, how do we change the views from other views? Well there are several possible ways to do this, but the easiest way is to add a Bindingfrom the child view directly to an ICommandin the MainViewModel. I use a custom version of the RelayComand, but you can use any type you like and I'm guessing that you'll get the picture:

最后,我们如何从其他视图更改视图?那么有几种可能的方式做到这一点,但最简单的方法是添加Binding从子视图直接连接到ICommandMainViewModel。我使用 的自定义版本RelayComand,但您可以使用任何您喜欢的类型,我猜您会得到图片:

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

In the child view XAML:

在子视图 XAML 中:

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

That's it! Enjoy.

就是这样!享受。

回答by Sandesh

Maybe thislink will help you. Just set the NavigateToproperty to the view which you need to display on the window.

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

As an example you can do something like

例如,您可以执行以下操作

<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>

Then the class file would be

然后类文件将是

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

        public ContentControl ViewContainer { get { return _viewContainer; } }

    }

Then you can define each view as UserControland then using the link I gave above bind the button's meffed:NavigationExtensions.NavigateTo="secondView". To target the ContentControlof the Windowjust use a RelativeSourcebinding. For e.g

然后你可以定义每个视图UserControl,然后使用我上面给出的链接绑定按钮的meffed:NavigationExtensions.NavigateTo="secondView". 要针对ContentControlWindow只是使用一个RelativeSource绑定。例如

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

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

In each of the view just see that you annotate the code behind class definition with the [NavigationView("firstview")]and so on.

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

It is complicated for first time but it will be very easy once you understand the idea.

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

回答by atomaras

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