我有一个ViewModel和两个Views。如何从ViewModel导航到View2。我在某个地方读到,我们需要使用PRISM,以便在Silverlight中从ViewModel打开多个视图。PRISM还有其他选择吗?
理想情况下,您不希望在视图模型中使用视图逻辑。您的视图模型不应该知道该视图的任何信息。对于视图模型来说,最好设置一个属性,让视图知道该导航了。这里有一个例子:
ViewModel:
using System.ComponentModel;
namespace ViewModels
{
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private bool _DoneDoingStuff;
public bool DoneDoingStuff
{
get
{
return _DoneDoingStuff;
}
set
{
if (_DoneDoingStuff != value)
{
_DoneDoingStuff = value;
NotifyPropertyChanged("DoneDoingStuff");
}
}
}
}
}
视图:
<navigation:Page
x:Class="Views.MyView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:vm="clr-namespace:ViewModels">
<navigation:Page.Resources>
<vm:MyViewModel
x:Key="MyViewModelInstance" />
</navigation:Page.Resources>
<Grid
x:Name="LayoutRoot"
DataContext="{Binding Source={StaticResource MyViewModelInstance}}">
<i:Interaction.Triggers>
<ei:DataTrigger
Binding="{Binding DoneDoingStuff}"
Value="True">
<ei:HyperlinkAction
NavigateUri="AnotherPage.xaml" />
</ei:DataTrigger>
</i:Interaction.Triggers>
</Grid>
</navigation:Page>
使用
DataTrigger
,其中Binding
属性设置为视图模型中的DoneDoingStuff
属性,Value
属性设置为"True"。当视图模型中的DoneDoingStuff
设置为true时,DataTrigger
将触发。现在您需要一个触发器操作来导航。使用
HyperlinkAction
并将NavigateUri
属性设置为要导航到的页面。请确保您的引用中有System.Windows.Interactive、System.Windows.Controls.Navigation和Microsoft.Expression.Interactions程序集。
一开始,这可能看起来太多了,但您的视图逻辑现在已经达到了需要的程度。
您不需要使用PRISM,但它可能是最好的。
我做这件事的一种方法(而且很草率)是有一个MainView页面,其中有一个导航框架,可以在启动时加载第一个视图。MainView必须是Page,而不是UserControl。您需要在xaml中有一个带有uri映射的导航框架,并在MainView页面的代码后面有一个声明为共享/静态的框架,然后设置框架的加载事件(在xaml),如下所示:
Public Shared MainContentFrame As Frame
Private Sub MainContentFrameXaml_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
MainContentFrame = TryCast(sender, Frame)
End Sub
然后在视图模型中,您可以调用:
MainView.MainContentFrame.Navigate(New Uri("/SecondView", UriKind.Relative))
这可能在某种程度上违反了MVVM模式,可能不是一个好的方法,但它是有效的。我以前就是这样做的,现在我用PRISM。