我有一个ViewModel和两个Views。如何从ViewModel导航到View2。我在某处读到了我们需要使用PRISM,从Silverlight中的ViewModel打开多个视图。 PRISM还有其他选择吗?
答案 0 :(得分:4)
理想情况下,您不希望在viewmodel中使用视图逻辑。您的viewmodel不应该知道有关视图的任何信息。对于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
属性设置为viewmodel中的DoneDoingStuff
属性,Value
属性设置为“True”。当您的viewmodel中的DataTrigger
设置为true时,DoneDoingStuff
会触发。
现在您需要一个触发操作来导航。使用HyperlinkAction
将NavigateUri
属性设置为您要导航到的页面。
请确保 System.Windows.Interactivity , System.Windows.Controls.Navigation 和 Microsoft.Expression.Interactions 参考文献中的装配。
起初,这可能看起来太多了,但您的视图逻辑现在已经到了需要的位置。
答案 1 :(得分:1)
您不需要使用PRISM,但它可能是最好的。
我已经完成它的一种方式(并且它很草率)是有一个MainView页面,其中包含一个导航框架,它将在启动时加载第一个视图。 MainView必须是Page而不是UserControl。您需要在xaml中使用带有uri映射的导航框架,并在MainView页面后面的代码中将框架声明为shared / static,然后设置框架的加载事件(在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
然后在viewmodel中你可以调用:
MainView.MainContentFrame.Navigate(New Uri("/SecondView", UriKind.Relative))
这可能在某种程度上违反了MVVM模式,可能不是一个很好的方法,但它确实有效。这就是我以前的做法,现在我使用PRISM。