2011-11-15 34 views
0

我正在寻找一种真正的解耦方式来支持使用MVVM的Silverlight应用程序中的导航。我试图完成更多的模式的“纯粹”实现,其中UI与ViewModel完全分离,以便应用程序实际上可以在没有UI的情况下完全运行。要做到这一点,我需要支持导航,而不用担心UI。ViewModel-Silverlight导航的第一种方法

我有几个想法如何实现这一点(与消息传递等),但还没有拿出一个好的方法来将View“映射”到ViewModel,以便UI在ViewModel被显示时显示适当的View “显示”。我记得前段时间遇到一篇文章描述了这个问题的解决方案,但似乎无法再在网上找到它。

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

+1

Caliburn.Micro救援... HTTP:// caliburnmicro.codeplex.com/ CM是专门设计用来处理这种情况的框架。它提供了一个伟大的ViewModel第一个实现框架。看看他们的例子,看看他们是否有帮助。 – EtherDragon

+0

我有一个开放的研究项目,调查更好的方法来做到这一点。发送我的电子邮件[email protected],我会告诉你我到目前为止。 –

回答

2

因此,这里是我的有点啰嗦说明我们落得这样做:

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

我还应该提到我们在我们的应用程序中使用MVVM Light和MEF。 (这在下面进行。)

为了做到这一点,我们创建了一个包含Frame控件的应用程序Shell(UserControl)。 Shell的DataContext被设置为ShellViewModel的一个实例,该实例公开一个CurrentPage属性(String类型)。然后,我们将框架的Source属性绑定到CurrentPage。这种方法与Rachel的应用级ViewModel类似。

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

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

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

这看起来运行良好,并给我们提供了一个非常MVVM-ish实现,所有导航都通过INavigationService和消息传递与ViewModel隔离。

现在唯一的缺点是,虽然我们在代码中使用字符串常量来表示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

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

View方面,我使用了一个ContentControl与它的Content势必CurrentPage,并使用DataTemplateSelector,以确定哪些View,以显示其ViewModel

这里有一个例子here如果你有兴趣,尽管它使用DataTemplates而不是DataTemplateSelector

相关问题