WPF 综合指南:MVVM 与 MVP
我很困惑。 也许你可以帮助我:)
我一直遵循 CAG 的指导,发现 MVP 模式对我来说非常自然。 假设我有一个 UI-ready 模型(例如:实现 INotifyPropertyChanged),我使用演示者将此模型绑定到视图(演示者知道视图的接口),使我的代码隐藏尽可能小,仅处理绑定(没有 ICommand 的控件的模型和命令)属性(或方法)或事件,在这种情况下立即委托给演示者。
过了一段时间,我发现了 MVVM 模式,但到目前为止我仍然无法理解它。 据我所知,只有当我的模型尚未准备好 UI 时,我才会使用 MVVM。 但是保留演示者并仅使用新模型会更合理吗?我无法理解这种用法会损失什么。 我知道我错过了一些东西,但它是什么:)。
此外,当您的视图是通用的并且可以处理多种模型(例如在 PropertyGrid 中)时。 建议将 ViewModel 与 DataTemplate 一起使用,但在这种情况下,您无法为模型中的每个实体创建模板,只需要在运行时进行调查,您会推荐什么?
观看 Josh Smith 在截屏视频中谈论 MVVM< /a>,我感觉在ViewModel中重新暴露Model违反了DRY(不要重复自己),这真的是不可避免的吗? 与火焰相比,没有人对此争论让我感到惊讶ADO.Net 动态数据元数据类现在正在发展。
希望它足够清楚,
谢谢
Ariel
I am confused. Maybe you can help me :)
I have been following the guidance of CAG and found the MVP pattern very natural to me.
Suppose I have a UI-ready Model (for example : implements INotifyPropertyChanged), I use the presenter to bind this Model to a view (presenter knows an interface of the view), keeping my Code-Behind as small as possible handling only Bindings (Model and Commands) properties (or methods) or events for controls that don't have ICommand and in this case immediately being delegated to the presenter.
After a while I've discovered the MVVM pattern, and so far it eludes me.
As far as I can tell in my approach I would use MVVM only when my Model is not UI-ready. But would it be more reasonable to keep the presenter and just use a new Model, I fail to understand what do I lose with this kind of usage.
I know I am missing something, but what is it :).Also when your View is generic and can handle many kinds of Models (such as in a PropertyGrid). ViewModel is recommended to be used with a DataTemplate, but in this case you just can't create a Template for each entity in your Model, it is just need to be investigated in runtime, what would you recommend?
While watching Josh Smith talking about MVVM in a screencast, I got a feeling that the re exposing of the Model in the ViewModel is violating DRY (do not repeat yourself), is it really unavoidable? it surprises me nobody his arguing about it in comparison for the flames ADO.Net Dynamic Data metadata classes are getting nowadays.
Hope it was clear enough
Thanks
Ariel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
关于#3,很多人会使用“另一层间接”论点,说模型的变化不会影响视图。 虽然这在技术上是正确的,但这并不是这样做的真正原因。
如果您将模型视为从数据访问层或服务(这是通常考虑的)返回的实体,您就会开始明白为什么需要 ViewModel。 ViewModel 旨在使用视图所需的行为来扩展模型。
例如。 如果您希望能够更改属性并通过绑定向视图通知此更改,则该属性需要引发某种形式的 NotifyPropertyChanged 以便视图可以做出反应。 这是典型模型不会有的行为。
在另一个示例中,假设您有一个集合,并且希望当用户单击视图中该项目旁边的复选标记时,使用布尔值标记集合中的每个项目。 您可能需要一个“IsSelected”属性。 这是模型不应该提供的行为。
不过我知道你来自哪里......一开始我确实遇到了问题。 当我第一次将模型的内容复制并粘贴到我的视图模型中时,我的胃翻了,但你只需要接受这样一个事实:为了让你的视图正常工作,它需要模型应该有的额外行为不提供。
不管这有多不干,强制 WCF 类型或 LINQ to SQL 类型(或任何您最喜欢的 ORM)实现 INotifyProperyChanged 都会更糟糕。
Regarding #3, a lot of people will use the "another layer of indirection" argument, saying that changes in the model won't affect the view. While this is technically correct, it's not the real reason to do something like this.
If you consider the Model as the entities you get back from, say, a data access layer or a service (which is what these are generally considered) you begin to see why you need a ViewModel. A ViewModel is designed to extend the model with behaviors the View needs.
For example. If you want to be able to change a property and have the View notified of this change through binding, the property needs to raise some form of NotifyPropertyChanged so that the view can react. This is behavior that your typical model won't have.
In another example, let's say you have a collection and you'd like to flag each item in the collection with a boolean value when a user clicks a checkmark next to that item in the view. You'd need an "IsSelected" property, probably. This is a behavior that the Model shouldn't have to provide.
However I see where you are coming from... I definitely had a problem with this at first. The first time I copy and pasted the contents of a model into my viewmodel, my stomach turned, but you just have to make peace with the fact that for your View to work, it's going to need this extra bit of behavior that a Model shouldn't provide.
No matter how un-DRY this is, forcing your WCF types or LINQ to SQL types (or whatever your favorite ORM is) to implement INotifyProperyChanged is worse.
除了上面的评论。 我想分享一下我个人对这种差异的一些理解。
通常在 MVP 中你有一个 View 界面,例如。 IView,抽象实际视图并将数据绑定到这些实际视图。 相反,在 MVVM 中,您通常使用实际视图的 DataContext,例如。 一个XAML用户控件,进行数据绑定,类似于MVP中的IView。 因此,不准确地说,两种模式的绑定是相似的。
主要区别在于 Presenter 与 ViewModel 部分。 视图模型与演示者有很大不同,演示者是 UI 和模型之间交换数据的桥梁。 正如其名称所示,它实际上是视图的模型。 ViewModel 中暴露的数据主要用于 UI 处理。 所以根据我的理解,在 MVVM 中,ViewModel 是视图的抽象。 与此相反,MVP主要使用IView来抽象视图。 因此,通常 MVVM 中的层数比 MVP 少,因此您可以编写更少的代码来在 MVVM 中完成相同的工作:
MVVM:模型 - ViewModel(表示实际视图,即 UI) - 实际视图
MVP:模型 - Presenter(桥梁)用于在模型和 UI 之间交换数据) - IView(代表实际视图,即 UI) - 实际视图
MVVM 相对 MVP 的优势主要基于 Microsoft 产品中的以下 2 个强大功能:
在 WPF 中占主导地位。 尽管已经有一些实现不在 Silverlight 运行时
WPF 和 Silverlight 中的 DataContext。
Besides the comments above. I would like to share some of my personal understanding on the difference.
Normally in MVP you have an interface of View, eg. IView, to abstract actual views and bind data to those actual views. In MVVM, instead, you normally use the DataContext of an actual view, eg. a XAML user control, to do databinding, which is similar to the IView in MVP. So let's say, inaccurately, the binding is similar on both patterns.
The major difference is on the Presenter vs ViewModel part. A view model is very different to a presenter which is a bridge for exchanging data between UI and model. It is actually, as what its name means, a model of the view. The data exposed in a ViewModel is mainly for UI process. So from my understanding, in MVVM, the ViewModel is an abstraction of views. In contrary to it, MVP mainly uses IView to abstract views. So normally there are few layers in MVVM than MVP and hence you can write less code to do the same job in MVVM:
MVVM: Model - ViewModel(represents actual views, ie. UI) - Actual Views
MVP: Model - Presenter(a bridge for exchanging data between model and UI) - IView(represents actual views, ie. UI) - Actual Views
The MVVM's advantage over MVP is mostly based on the following 2 great features in Microsoft products,
Commanding in WPF. It could be avilable in Silverlight in the future although there are already some implementations which are not in the Silverlight runtime
DataContext in WPF and Silverlight.
广告.3。 通过在 ViewModel 中公开 Model,您可能会觉得重复自己,但您真正做的是抽象 Model,以便 View 仅了解此抽象(View 仅了解 ViewModel)。
这是因为对模型的更改不应破坏视图。 此外,您的模型可以实现为从不同来源获取数据的许多不同服务。 在这种情况下,您不希望 View 了解所有这些,因此您创建了另一个抽象 - ViewModel。
Ad.3. It may seem that you repeat yourself by exposing Model in ViewModel, but what you really do is abstracting the Model, so that View knows only about this abstraction (View knows only about ViewModel).
This is because changes to Model shouldn't break the View. Also, your Model can be implemented as many different services that get data from different sources. In this case you wouldn't like View to know about all of them, so you create another abstraction - ViewModel.
如果演示者知道视图的接口,那么您要么需要演示者使用的所有视图都具有相同的接口,要么为每个视图创建一个演示者。 使用 MVVM,视图了解 viewModel,而 viewModel 也了解模型(但反之则不然)。 这意味着多个视图可以使用一个虚拟机,多个虚拟机可以使用一个模型。
我不太确定你在第二点中要问什么。 VM 不是视图(或不知道视图),对我来说,DataTemplate 定义了对象的显示方式。 我将我的 DataTemplates 放入 ResourceDictionary 中,它绝对属于视图。 我的 VM 层中唯一的 WPF“东西”是命令。
我需要更多信息来回答你的第三点。 如果您更深入地研究 MVVM,也许它会自己找到答案。
这是我的相关帖子,可能会对您有所帮助
祝你好运。
If the presenter knows the interface of the view, you either need all views used by a presenter to have the same interface or make a presenter for each view. With MVVM the view is aware of the viewModel, and the viewModel is aware of the model (but not vise versa). This means that multiple views can use a VM and multiple VMs can use a Model.
I'm not quite sure what you're asking in your 2nd point. The VM is not the View (or aware of the Views) and to me a DataTemplate defines how an object is displayed. I put my DataTemplates in a ResourceDictionary which definitely belongs in the View. The only bits of WPF 'stuff' in my VM layer are Commands.
I need a little more information to answer your 3rd point. Perhaps it'll answer itself if you dig a little deeper into MVVM.
Here's a related post of mine which might help you
Good luck.