2011-02-28 79 views
2

这似乎是一个非常天真的问题,但究竟是从一个页面之外获得NavigationService,比如说可能是视图模型?大家都说导航应该发生在视图上,但我一直在想,这不是一个网页,它是一个应用程序。视图模型和业务逻辑应控制应用程序流,而不是视图。这实际上是天真的吗?如何在不成为页面的情况下获得NavigationService?

回答

2

据我所知,涉及视图的操作,即UI,应该由视图独占完成。在使用MVVM时,UI不应该直接由ViewModel或BusinessLogic控制(因为他们不应该了解有关View的具体实现的任何内容),但可以使用Messages。这意味着,如果我们想从ViewModel打开一个编辑器窗口,我们会从ViewModel发送一条消息,我们要打开它并在View中接收它并在那里打开窗口。这同样适用于浏览不同的页面,在这里您将收到MainPage中的消息(或任何需要浏览的页面)并处理所有内容。

另一种方法是使用DialogService或类似的东西,它可以在中心位置处理打开的窗口。但是,由于NavigationService是Page类的一个属性,我们需要处理Page中的消息。

示例代码,使用MVVM Light Toolkit:(未测试,部分肖恩Wildermuth的RiaXBoxGames example拍摄):

视图模型(例如,把在一个按钮命令):

Messenger.Default.Send<bool>(true, "GoToNextPage"); 

查看(例如,把在一个构造函数):

Messenger.Default.Register<bool>(this, "GoToNextPage", ignore => 
{ 
    // your code to go to next page 
}); 
+2

我喜欢你的方法,但我发现了一种不会触及视图代码的方法。我公开了一个服务(使用MEF),可以直接访问Frame控件(或实现'Inavigate'的其他任何东西)。是的,它在MainPage视图上重要一点(我要求视图向服务提供Frame控件),但Silverlight Navigation Framework显然是这样。该服务作为该框架的逻辑附录适用于我的应用程序,并且工作得非常好。我甚至有一个映射层,可以将已知的模块名称... – Jordan 2011-03-01 16:58:41

+0

...将视图模型转换为Uri的视图模型,我的自定义内容加载器可以从任何模块中理解和加载。该层由每个模块单独提供,因此视图名称保留在模块级别范围内。 – Jordan 2011-03-01 17:02:57

1

另一种选择是,当命令发生上创建视图模型的事件,触发此事件nd subscribe查看此事件。在EventArgs内部,您可以携带哪个页面进行导航等。我认为这是一个简单且可测试的解决方案。

Robert

0

我只是在创建视图模型时传递对框架的引用。

相关问题