16

我很困惑。也许你可以帮助我:)

我一直遵循 CAG 的指导,发现 MVP 模式对我来说非常自然。假设我有一个 UI 就绪模型(例如:实现 INotifyPropertyChanged),我使用演示者将此模型绑定到视图(演示者知道视图的接口),使我的代码隐藏尽可能小,仅处理绑定(模型和命令)属性(或方法)或没有 ICommand 的控件的事件,在这种情况下立即委托给演示者。

  1. 一段时间后,我发现了 MVVM 模式,但到目前为止我还没有发现它。据我所知,我只会在我的模型未准备好 UI 时使用 MVVM。但是保留演示者并只使用新模型是否更合理,我不明白这种用法会失去什么。我知道我错过了一些东西,但它是什么:)。

  2. 此外,当您的 View 是通用的并且可以处理多种模型(例如在 PropertyGrid 中)时。建议 ViewModel 与 DataTemplate 一起使用,但在这种情况下,您无法为模型中的每个实体创建模板,只需要在运行时进行调查,您会推荐什么?

  3. 看 Josh Smith 在截屏中讲 MVVM 的时候,我有一种感觉,在 ViewModel 中重新暴露 Model 违反了 DRY(不要重复),真的无法避免吗?与现在 ADO.Net 动态数据元数据类的火焰相比,没有人对此争论不休,这让我感到惊讶。

希望它足够清楚

谢谢

爱丽儿

4

4 回答 4

20

关于#3,很多人会使用“另一层间接”的说法,说模型的变化不会影响视图。虽然这在技术上是正确的,但这并不是这样做的真正原因。

如果您将模型视为您从数据访问层或服务(通常被认为是这些)返回的实体,您就会开始了解为什么需要 ViewModel。ViewModel 旨在使用 View 需要的行为扩展模型

例如。如果您希望能够更改属性并通过绑定通知视图此更改,则该属性需要引发某种形式的 NotifyPropertyChanged 以便视图可以做出反应。这是您的典型模型不会有的行为。

在另一个示例中,假设您有一个集合,并且当用户单击视图中该项目旁边的复选标记时,您希望使用布尔值标记该集合中的每个项目。您可能需要一个“IsSelected”属性。这是模型不应该提供的行为。

但是我知道你来自哪里......我一开始肯定有这个问题。我第一次将模型的内容复制并粘贴到我的视图模型中时,我的胃转了,但你只需要接受这样一个事实,即要让视图工作,它需要模型应该有的这种额外行为不提供。

无论这是多么不干燥,强制您的 WCF 类型或 LINQ to SQL 类型(或任何您最喜欢的 ORM)来实现 INotifyProperyChanged 会更糟。

于 2009-09-04T17:18:49.817 回答
6

除了上面的评论。我想分享一些我个人对差异的理解。

通常在 MVP 中你有一个 View 接口,例如。IView,用于抽象实际视图并将数据绑定到这些实际视图。相反,在 MVVM 中,您通常使用实际视图的 DataContext,例如。一个 XAML 用户控件,用于进行数据绑定,类似于 MVP 中的 IView。因此,假设不准确,两种模式的绑定相似。

主要区别在于 Presenter 与 ViewModel 部分。视图模型与演示者非常不同,演示者是 UI 和模型之间交换数据的桥梁。实际上,正如它的名字一样,它是视图的模型。ViewModel 中暴露的数据主要用于 UI 流程。所以据我了解,在 MVVM 中,ViewModel 是视图的抽象。与之相反,MVP 主要使用 IView 来抽象视图。所以通常 MVVM 中的层数比 MVP 少,因此您可以编写更少的代码来在 MVVM 中完成相同的工作:

MVVM: Model - ViewModel(代表实际视图,即UI) - Actual Views

MVP:Model - Presenter(模型和 UI 之间交换数据的桥梁) - IView(代表实际视图,即 UI) - Actual Views

MVVM 相对于 MVP 的优势主要基于 Microsoft 产品中的以下 2 个强大功能,

  1. WPF 中的命令。尽管已经有一些实现不在 Silverlight 运行时中,但它可能会在未来的 Silverlight 中可用

  2. WPF 和 Silverlight 中的 DataContext。

于 2009-09-02T00:34:34.413 回答
6

广告 3。看起来你在 ViewModel 中暴露 Model 似乎是在重复自己,但你真正做的是抽象 Model,让 View 只知道这个抽象(View 只知道 ViewModel)。

这是因为对模型的更改不应破坏视图。此外,您的模型可以实现为从不同来源获取数据的许多不同服务。在这种情况下,您不希望 View 了解所有这些,因此您创建了另一个抽象 - ViewModel。

于 2009-05-08T10:57:01.580 回答
5

如果演示者知道视图的界面,您要么需要演示者使用的所有视图具有相同的界面,要么为每个视图创建一个演示者。使用 MVVM,视图知道 viewModel,而 viewModel 知道模型(反之亦然)。这意味着多个视图可以使用一个 VM,多个 VM 可以使用一个模型。

我不太确定您在第二点中要问什么。VM 不是视图(或不知道视图),对我来说,DataTemplate 定义了对象的显示方式。我将我的 DataTemplates 放在绝对属于视图的 ResourceDictionary 中。我的 VM 层中唯一的 WPF“东西”是命令。

我需要更多信息来回答您的第三点。如果您深入了解 MVVM,也许它会自行回答。

这是我的相关帖子,可能会对您有所帮助

祝你好运。

于 2009-05-08T10:47:01.823 回答