ViewModel-Silverlight导航的第一种方法

时间:2011-11-15 20:25:09

标签: silverlight mvvm navigation

我正在寻找一种使用MVVM在Silverlight应用程序中支持导航的真正解耦方式。我正在尝试完成更多的模式的“纯粹”实现,其中UI与ViewModel完全分离,以便应用程序实际上可以在没有UI的情况下完全运行。为此,我需要在没有UI问题的情况下支持导航。

我有几个想法如何实现这一点(使用Messaging等)但没有提出一种将View“映射”到ViewModel的好方法,以便UI可以在ViewModel“时”显示相应的View。显示”。我记得很久以前发过一篇文章描述了这个问题的解决方案,但似乎无法在网上找到它。

有谁知道如何找到这篇文章或有任何解决这个问题的经验?

2 个答案:

答案 0 :(得分:2)

所以这里有点冗长的描述我们最终做了什么:

首先,我们决定使用内置的页面导航框架。我们有多种原因,但由于它是内置的,并且也是Windows 8中的导航框架,我们选择尝试这种方法。

我还应该提到我们在应用程序中使用MVVM Light和MEF。 (这在下面发挥作用。)

为了使这项工作,我们创建了一个包含Frame控件的应用程序Shell(UserControl)。 Shell的DataContext被设置为ShellViewModel的一个实例,它暴露了一个CurrentPage属性(String类型)。然后我们将Frame的Source属性绑定到CurrentPage。这种方法类似于Rachel的应用级ViewModel。

ShellViewModel向Messenger注册以接收CurrentPageChanged消息。收到消息后,将更新CurrentPage属性,引发PropertyChanged事件并更新UI。该消息源自NavigationService(实现INavigationService并使用MEF注入/导入)。

NavigationService公开一个NavigateTo方法,该方法接受表示目标的ViewModel的字符串名称。此名称与导出时使用ViewModel的合同名称(使用MEF)匹配,并用于使用ViewModelLocator查找实例。

在NavigateTo方法中,我们使用ViewModelLocator检索ViewModel实例,在当前ViewModel上调用Deactivate(如果有),在新ViewModel上调用Activate,然后发送带有新视图名称的CurrentPageChanged消息作为参数。 Activate / Deactivate是ViewModel上的辅助方法,允许我们在ViewModel导航或导航时执行任何必要的任务。

这似乎运行良好,并为我们提供了一个非常MVVM-ish的实现,所有导航都通过INavigationService和消息传递与ViewModels隔离。

现在唯一的缺点是,虽然我们在代码中使用字符串常量来表示ViewModel名称,但我们仍然在视图中对字符串进行硬编码以设置DataContext。我将研究一种自动设置DataContext的方法,作为导航“工具”的一部分。

我应该提一下,这种方法是从许多来源一起解析的,包括(但不限于)Rachel和以下链接:

http://blogs.microsoft.co.il/blogs/eladkatz/archive/2011/01/25/adapting-silverlight-navigation-to-mvvm.aspx

http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx

http://www.geoffhudik.com/tech/2010/10/10/another-wp7-navigation-approach-with-mvvm.html

答案 1 :(得分:1)

通常我对整个应用都有一个ViewModel,它包含CurrentPage和所有导航事件处理。

View方面,我使用ContentControlContent绑定到CurrentPage,然后使用DataTemplateSelector确定View ViewModel }显示DataTemplates

如果您感兴趣,可以使用示例here,但它使用DataTemplateSelector代替{{1}}。