MVVM:哪个组件负责导航?

时间:2013-06-01 14:42:17

标签: c# asp.net windows-phone-7 mvvm

我正在开发Windows Phone 7应用程序。现在我需要在用户点击指定按钮后切换视图,该按钮将用户带到另一个视图。

理论上,MVVM中的哪个组件应该负责导航,即切换视图?代码片段很适合展示演示。

我已经尝试在View中插入切换代码并且它可以正常工作,但我遇到了一种情况,我调用异步Web服务并且只想在操作完成后导航用户到新视图,导航代码应该在事件处理程序内。

谢谢。

P / S:我的项目截止日期即将到来,我没有时间使用MVVM Light,Caliburn Micro等MVVM工具重建我的项目。

3 个答案:

答案 0 :(得分:2)

我在基类中放置了一个我所有ViewModel共享的Navigate方法:

protected void Navigate(string address)
{
    if (string.IsNullOrEmpty(address))
        return;

    Uri uri = new Uri(address, UriKind.Relative);
    Debug.Assert(App.Current.RootVisual is PhoneApplicationFrame);
    BeginInvoke(() =>
        ((PhoneApplicationFrame)App.Current.RootVisual).Navigate(uri));
}

protected void Navigate(string page, AppViewModel vm)
{
    // this little bit adds the viewmodel to a static dictionary
    // and then a reference to the key to the new page so that pages can
    // be bound to arbitrary viewmodels based on runtime logic
    string key = vm.GetHashCode().ToString();
    ViewModelLocator.ViewModels[key] = vm;

    Navigate(string.Format("{0}?vm={1}", page, key));
}

protected void GoBack()
{
    var frame = (PhoneApplicationFrame)App.Current.RootVisual;
    if (frame.CanGoBack)
        frame.GoBack();
}

因此,如果您要求的话,ViewModel基类会执行导航。然后,通常一些派生的ViewModel类控制导航的目标,以响应绑定到View中按钮或超链接的ICommand的执行。

protected SelectableItemViewModel(T item)
{
    Item = item;
    SelectItemCommand = new RelayCommand(SelectItem);
}

public T Item { get; private set; }

public RelayCommand SelectItemCommand { get; private set; }

protected override void SelectItem()
{
    base.SelectItem();
    Navigate(Item.DetailPageName, Item);
}

因此View只知道何时需要导航操作并且ViewModel知道去哪里(基于ViewModel和Model状态)以及如何到达那里。

答案 1 :(得分:0)

视图应包含有限数量的可能目的地。如果您必须在每个页面上都有一个顶级导航,那么它应该是您的布局的一部分,或者您可以将它们放在子视图中。

答案 2 :(得分:0)

我将MVVM外部的导航放在一个负责显示/隐藏视图的类中。

ViewModels使用带有弱点的消息代理来向此类发布消息。

这个设置给了我最大的自由,并且没有在不属于那里的MVVM类中承担任何责任。