Silverlight 3 Beta,ViewModel中的NavigationService

3
我正在开发一个Silverlight 3 Beta导航应用程序,因此我采用了略微变化的MVVM模式 :) (全局视图模型),使用Prism等内容。
问题:如何在ViewModel中导航到不同的“NavigationPage”?
长话短说,ViewModel被声明为页面资源。
<navigation:Page.Resources>
    <mvvm:LoginModel x:Key="DataSource" d:IsDataSource="True"></mvvm:LoginModel>
</navigation:Page.Resources>

然后使用一条命令将所有内容与视图模型连接起来。
<Button x:Name="LoginButton" Width="100"  Margin="8" Content="Login"
        prism:Click.Command="{Binding LoginCommand}"/>

现在,如果我尝试在视图模型中导航到任何地方,像这样:
this.NavigationService.Navigate(new Uri("/Views/About.xaml", UriKind.Relative));

导航服务为空,我找到了this篇文章,讲述了如何使用Helix 0.3进行导航,这是在SL2时期构建的,当时导航控件还不存在。现在Helix的模型运行良好,通过在ViewModel中实现INavigationAware,您可以访问NavigationContext,然后执行所需操作,我已经尝试过Helix,它运行良好。
SL3带有内置的导航支持,可以说与Helix相同。因此,我不想使用第三方框架,而是更喜欢使用内置的SL3功能。
SL3中是否有类似于Helix的INavigationAware接口的东西?
5个回答

4

我个人认为NavigationService是与UI Frame或Page相关的UI概念。

另一种在不需要将NavigationService传递到视图模型中的情况下完成此操作的方法是,当需要导航时,视图模型引发一个事件...视图处理视图模型事件并响应调用Navigate。


我完全同意,好的,所以我创建了一个事件,当ViewModel请求导航时触发。然后从View中仍然需要访问Page资源中的视图模型(像之前的解决方案)。只是这一次,我不会将导航服务添加到ViewModel中,而是告诉View监听事件并相应地进行导航,对吗? - Neil
没错,你懂的...不需要将NavigationService之类的东西传递到视图模型中。 - Nikhil Kothari

1
一个不太正规的解决方法,但这是我能用来让它工作的唯一方法。 在视图的OnNavigatedTo事件中,访问ViewModel并将NavigationService设置为ViewModel中的属性,以便稍后在ViewModel中使用。
    protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            ViewModels.LoginViewModel viewmodel = (ViewModels.LoginViewModel)this.Resources["DataSource"];
//DataSource being the x:Name given to the viewmodel that is loaded as a page resource
            viewmodel .service = NavigationService;
        }

1
如果您正在使用MVVM light,您可能希望考虑使用消息系统。在承载框架的页面上添加一个监听器来进行导航,并从您的视图模型发送导航消息。

0

好的,为了帮助我的问题得到解答,因为还没有任何答案,我将提供更多信息。

这是视图模型中的代码

public LoginModel()
    {
        LoginCommand = new DelegateCommand<object>(LoginCommandExecuted, a => { return _CanLoginCommandExecute; });
    }

    public ICommand LoginCommand { get; private set; }
    private bool _CanLoginCommandExecute = true;
    private void LoginCommandExecuted(object parameter)

    {
        _CanLoginCommandExecute = false;

        AdminClient client = new AdminClient();
        client.AuthorizeAsync();
        client.AuthorizeCompleted += 
        new EventHandler<AsyncCompletedEventArgs>(
                (s, e) =>
                {
                    if (e.Error != null)
                    {
                        MessageBox.Show("Login Failed");
                    }
                    else
                    {
                        this.NavigationService.Navigate(new Uri("/Views/About.xaml", UriKind.Relative));
                    }
                    _CanLoginCommandExecute = true;
                }
                );

    }

NavigationService为null,所以我无法跳转到下一个视图,请帮忙!!!


到目前为止,这是我找到的最接近解决方案的东西>> http://blogs.southworks.net/mconverti/2009/04/12/how-to-integrate-a-prism-v2-application-with-the-silverlight-3-navigation-framework/#_Download - Neil

0
NavigationService.Navigate(new Uri("/About", UriKind.Relative));

上面应该可以工作。


在ViewModel中无法访问NavigationService,因此View必须订阅一个事件,当ViewModel希望View代表它导航时,ViewModel将触发该事件。这是一种以View为先的MVVM方法。 - Neil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接