我认为我认为Silverlight中的一个相当简单的问题,我想用MVVM原理解决它,主要是为了增强我自己的理解。
假设我有一个简单的LOB应用程序,旨在让我加载并编辑单个Employee(仅作为示例,为了解释)。在我的例子中,Employee由许多复杂的对象组成 - 一个Employee有一个ContactInfo,一个技能组,一个EmploymentHistory,一个AwardEarned等等。这个想法是我可以让这个应用加载一个员工并获得访问权限。许多不同的编辑器屏幕。 Employee的每个组件都有自己的编辑器屏幕。
在视觉上,该应用程序只是一个左侧导航栏和右侧的主视图。导航栏只允许我输入员工编号并将其作为“活动”员工加载到内存中。它有一个简单的链接列表 - 单击链接应该在右侧加载相应的编辑器屏幕。
有几个概念我认为我不太了解,而且我无法继续进行。我知道有一种方法可以让猫皮肤变亮,特别是涉及到WPF / Silverlight / XAML / MVVM时,但是我无法思考所有不同的概念及其重现。
View-First或ViewModel First
在考虑了MVVM之后,对我来说最自然的是Josh Smith在他经常引用的文章中看起来promote的视图模型构成的概念。这里的想法似乎是你通过将视图模型组合在一起来模拟你的UI,然后你让视图模型通过类型化的DataTemplates自我渲染。这感觉就像是对我的一个非常好的分离,它也使视图模型的通信非常直接和易于理解。
当然,对于许多投诉,Silverlight在DataTemplates上没有DataType属性:one,two。无论如何,我认为比viewmodel组合更频繁地提升的是更多视图优先设计,其中视图的视图模型通常在视图的XAML中或通过DI容器实例化,这意味着您无法将任何参数交给它。我很难理解这一点:如果我从来没有告诉它模型中的数据是什么,ViewModel应该如何为View提供模型?通过视图到达其viewmodel似乎也没有意义。我在这个领域非常模糊,但似乎接受的答案是“使用中介/轻量级消息传递框架”。我现在正在浏览MVVMLight中的消息传递系统的一些教程,我将会看到类似的东西,如果只是为了理解这些概念,但是如果有人能够对此有所了解,我会非常关注欣赏它。任何涉及Unity / Prism或MEF的东西都是有效的,但我在寻求知识方面还没有那么远: - )
实例化视图并选择它们
理论上(我说因为SL不支持DataTemplate DataType),viewmodel组合方法可以使这非常简单。我可以让屏幕的右侧是一个内容控件,其Content属性绑定到一个名为ActiveEditor的属性。超链接的参数化命令会将ActiveEditor设置为给定的视图模型。
使用更多基于视图的方法,我将如何处理此问题?首先想到的是实例化主视图的XAML中的所有控件。
操纵ContentControl的Content属性是解决这种情况的好方法,还是我最好做一些事情,例如设置每个控件的可见性?
答案 0 :(得分:1)
编写ViewModel(VM)以便它与模型“连接”但完全不了解View - 实际上,这是单元测试的最佳选择(see NUnit )因为它不知道,并且它关心的是它是否被UI或测试框架使用。
VM公开实现ICommand接口的公共CLR属性,View,使用(一般来说无论如何)使用其默认构造函数实例化VM,然后将其Buttons / Hyperlinks等绑定到这些Command属性,如。因此,例如,您可能有一个暴露CloseCommand以退出应用程序的VM,View可能包含一个绑定到该命令的MenuItem,例如:
<MenuItem Header="E_xit" Command="{Binding Path=CloseCommand}" />
现在,VM还会公开要在UI中显示的对象的公共ObservableCollection。是否将此ObservableCollection作为VM构造函数的一部分填充,或者是否通过UI交互(比如指定给Button单击的另一个Command)来填充它取决于您,但最终结果是您将View控件绑定到此公开的ObservableCollection在XAML中如:
<y:DataGrid ItemsSource="{Binding Breakdown}"/>
或equivelant用于显示数据的任何控件(不确定DataGrid在Silverlight中与WPF相比具有哪些元素)。
同时......:Mediator模式用于VM相互交互,而不是View与VM交互。例如,您可能有一个自定义的TreeView,它在与主图表屏幕相同的View上有自己的VM。在这种情况下,您可以使用Mediator为TreeView的VM与图表VM进行通信。
至于你问题的最后一点,我想在你提到的文章中使用Josh Smith的方式建立一个基本框架,并使用该方法将其他ViewModel添加到你的silverlight应用程序的右侧。
希望至少有所帮助。