如何从silverlight中的viewmodel从一个视图导航到另一个视图?

I have one ViewModel and two Views. How can I navigate to View2 from ViewModel. I read somewhere that we need to use PRISM, for opening multiple Views from ViewModel in Silverlight. Is there any alternative for PRISM?

#0

Ideally you do not want to use view logic in your viewmodel. Your viewmodel should not know anything about the view. It would be a better idea for your viewmodel to set a property letting the view know it's time to navigate. Here's an example:

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");
                }
            }
        }
    }
}

View:

<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>
  • Use a DataTrigger with Binding property set to the DoneDoingStuff property from your viewmodel, and the Value property set to "True". The DataTrigger will trigger when DoneDoingStuff from your viewmodel is set to true.

  • Now you need a trigger action to navigate. Use HyperlinkAction with the NavigateUri property set to the page you're navigating to.

  • Be sure to have System.Windows.Interactivity, System.Windows.Controls.Navigation, and Microsoft.Expression.Interactions assemblies in your references.

At first, this might seem to be too much, but your view logic is now where it needs to be.

#1

You don't need to use PRISM, but it might be best.

One way that I have done it (and it is sloppy) is to have a MainView page that has a Navigation frame in it that will load the first view on start up. The MainView has to be a Page and not a UserControl. You need to have a navigation frame with uri mappings in the xaml and have a frame declared as shared/static in the code behind of the MainView Page and then set the loaded event (in the xaml) of the frame like so:

Public Shared MainContentFrame As Frame
Private Sub MainContentFrameXaml_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
    MainContentFrame = TryCast(sender, Frame)
End Sub

Then in the viewmodel you can just call:

MainView.MainContentFrame.Navigate(New Uri("/SecondView", UriKind.Relative))

This probably violates the MVVM pattern in some way and may not be a good way to do it, but it works. This is how I used to do it, now I use PRISM.

推荐文章

开源codeplex库可以用于商业目的吗?

开源codeplex库可以用于商业目的吗?

推荐文章

在解析文本时,是否有一个好的CPAN模块来实现状态机?

在解析文本时,是否有一个好的CPAN模块来实现状态机?

推荐文章

Appengine python API调用邮件。发送()响应时间过长,已取消

Appengine python API调用邮件。发送()响应时间过长,已取消

推荐文章

Java-给特定的位模式位置,一个特定的值

Java-给特定的位模式位置,一个特定的值

推荐文章

运行测试/单元/RbcTest.php从bash脚本目录无法工作

运行测试/单元/RbcTest.php从bash脚本目录无法工作

推荐文章

在eclipse中使用sonar插件

在eclipse中使用sonar插件

推荐文章

scala lift-带多个参数的filterNot

scala lift-带多个参数的filterNot

推荐文章

InvalidCastException错误,清除日期选择器的值

InvalidCastException错误,清除日期选择器的值

推荐文章

CalendarStoreAPI低于10.7-重复日历?

CalendarStoreAPI低于10.7-重复日历?

推荐文章

如何从服务层访问EF类属性

如何从服务层访问EF类属性

推荐文章

使用java和UTF-16LE到UTF-8的转换打开xls文件并将其保存为tsv文件

使用java和UTF-16LE到UTF-8的转换打开xls文件并将其保存为tsv文件

推荐文章

面向对象的c通道块参数化设计

面向对象的c通道块参数化设计

推荐文章

如何从Linq查询中排除一个对象类型

如何从Linq查询中排除一个对象类型

推荐文章

获取编码器控制器内的地理位置

获取编码器控制器内的地理位置

推荐文章

高度和宽度的自动调整掩码

高度和宽度的自动调整掩码

推荐文章

使用为Twitter API创建webrequest POSTVB.NET版

使用为Twitter API创建webrequest POSTVB.NET版