我正在开发Windows Phone 7应用程序。现在我需要在用户点击指定按钮后切换视图,该按钮将用户带到另一个视图。
理论上,MVVM中的哪个组件应该负责导航,即切换视图?代码片段很适合展示演示。
我已经尝试在View中插入切换代码并且它可以正常工作,但我遇到了一种情况,我调用异步Web服务并且只想在操作完成后导航用户到新视图,导航代码应该在事件处理程序内。
谢谢。
P / S:我的项目截止日期即将到来,我没有时间使用MVVM Light,Caliburn Micro等MVVM工具重建我的项目。答案 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类中承担任何责任。