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
WPF MVVM navigate views
提问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.
我试过这些东西,但不能让它工作。
- How to navigate through windows with MVVM Light for WPF?
- https://galasoft.ch/posts/2011/01/navigation-in-a-wp7-application-with-mvvm-light
- 如何使用 MVVM Light for WPF 浏览窗口?
- https://galasoft.ch/posts/2011/01/navigation-in-a-wp7-application-with-mvvm-light
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 PersonViewModel
and a CompanyViewModel
, each with their own related view and each extending an abstract
base class BaseViewModel
.
首先,您不需要任何这些工具包/框架来实现 MVVM。它可以像这样简单......让我们假设我们有一个MainViewModel
,并PersonViewModel
和一个CompanyViewModel
,每个都有自己的相关看法和各延伸出的abstract
基类BaseViewModel
。
In BaseViewModel
, we can add common properties and/or ICommand
instances and implement the INotifyPropertyChanged
interface. As they all extend the BaseViewModel
class, we can have this property in the MainViewModel
class 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 INotifyPropertyChanged
interface correctly on yourproperties unlike this quick example. Now in App.xaml
, we declare some simple DataTemplate
s to connect the views with the view models:
当然,你会实现INotifyPropertyChanged
上正确接口你不像这个简单的例子性能。现在App.xaml
,我们声明一些简单的DataTemplate
s 来连接视图和视图模型:
<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 BaseViewModel
instances in our application, these DataTemplate
s will tell the framework to display the related view instead. We can display them like this:
现在,无论我们BaseViewModel
在应用程序中使用我们的哪个实例之一,这些DataTemplate
s 都会告诉框架显示相关的视图。我们可以像这样显示它们:
<ContentControl Content="{Binding ViewModel}" />
So all we need to do now to switch to a new view is to set the ViewModel
property from the MainViewModel
class:
所以我们现在需要做的就是切换到一个新的视图,ViewModel
从MainViewModel
类中设置属性:
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 Binding
from the child view directly to an ICommand
in 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
从子视图直接连接到ICommand
的MainViewModel
。我使用 的自定义版本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 NavigateTo
property 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 UserControl
and then using the link I gave above bind the button's meffed:NavigationExtensions.NavigateTo="secondView"
. To target the ContentControl
of the Window
just use a RelativeSource
binding. For e.g
然后你可以定义每个视图UserControl
,然后使用我上面给出的链接绑定按钮的meffed:NavigationExtensions.NavigateTo="secondView"
. 要针对ContentControl
的Window
只是使用一个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}}"/>