2011-10-31 110 views
3

不久之前,我开始为WPF编写一个对接库(类似于Avalon)。那时候我的目标是用MVVM的方式来学习。为了让事情顺利进行,我决定首先设计模型零件的视图,并且认为我稍后会在之间放入一些视图模型。现在,我完成了所有视图和模型的工作:视图获取模型并直接与它交谈,而模型暴露一系列事件以盲目通知听众。而且,它的每个视觉方面都可以在XAML中进行重新设置/模板化。事情工作得很好。现在我被困在视图模型部分。由于这种类型的库的性质(内容变化和动态重新创建),还有很多代码仍然要写在视图的代码隐藏部分中,而且我真的没有看到也有必要为每个视图编写一堆视图模型类。也许在几个地方使用一些绑定/指令会很方便,但我并不认为它能弥补完成纯MVVM设计所需的所有重构。我真的需要MVVM吗?

我明白MVVM设计的优点,我非常喜欢它,但在这种情况下,我无法看到视图模型如何为整个事物增加任何价值。

任何想法,建议或更正将不胜感激。

在此先感谢。

+2

有帮助的一件事是与模型没有1对1映射的视图。如果您想在一个视图中显示来自两个相关实体的信息,那么使用该数据填充视图模型是有意义的。 – Garvin

回答

12

这里的部分问题是,您正在有效地制作控件库 - 因此,您正在开发的东西完全属于MVVM中的“视图”。尽管你可能会迫使一个MVVM-ish“模型”到位,但它可能会让你的代码浑浊起来。请记住,MVVM旨在将应用程序特定的逻辑和数据连接到View - 但在这种情况下,您的“逻辑和数据”就是View本身,就像您正在编写控制库一样。从模型中分离视图并没有太多意义 - 因为模型已经是视图的一部分了。

我并不是说干净分离问题并不重要,但在这种情况下,根据MVVM考虑这个问题可能不太合适。该模型与视图没有分离,并试图完全分离它并在其间添加另一个抽象层可能会增加复杂性而没有收益。

如果您正在制作自定义控件库,那么目标不应该是使用MVVM编写它,而是要确保您的控件在MVVM应用程序中使用时可以清理。这通常意味着确保你的控件都暴露出所有内容和设置的适当依赖属性,并且它们与数据绑定等干净地工作。事实上,事件通常不是必需的,至少不是那么多,并且具有单独的“模型类”层次结构会阻碍用户的使用 - 用户希望能够直接在该控件上放下控件并绑定到属性,这几乎可以保证您的控件将有代码隐藏。

它是一个谬论,自动假定MVVM是恰当的,因为你正在使用WPF或Silverlight。 MVVM适用于某些类型的应用程序,但控件(或控件库)不一定就是其中之一。

+0

+1我的想法正是如此。然而,一件重要的事情是:在适用的情况下,使控件“MVVM友好”。我已经处理了很多在MVVM上下文中很难使用的控件,并且最多只需要子类化,或者最糟糕的是需要“违反规则”,这仅仅是因为控件设计得不好。 – MetalMikester

+0

@MetalMikester这是我的第4段的整点...;) –

+2

我完全不知道我是如何错过了第一次阅读。 *看日历*嘿,我可以在星期一责怪它! – MetalMikester

1

如果代码背后有很多代码 - 你没有以正确的方式使用MVVM,大部分事情都可以用MVVM方式完成 - 通过使用绑定或命令在View或ViewModel中实现。

我无法看到视图模型如何为整个事物增加任何价值。

视图模型提供:

  • 模型本身,很多时候视图模型封装模型本身(当没有需要替换在同一视图模型不同型号)
  • 数据由udnerlying模型暴露(因为视图模型绑定查看的DataContext,而不是模型本身)
  • 命令处理逻辑
  • 标志,简化生活的视图 - 例如公开标志像bool IsValid所以视图c渲染绿色背景而不是红色(简化以显示逻辑封装和责任授权)
+0

并不是我不应该写这么多的代码隐藏。它更像是这种应用*需要*很多代码隐藏。 – Trap

+0

@Trap:我认为这个*库*(不是真正的应用程序)应该有代码... –

+0

@ReedCopsey:是的我的意思是*库*而不是应用程序* :)。我不认为我理解你的评论。你将如何处理所有的视图?我必须动态地创建/删除控件,调整大小,更新位置等。这个代码应该放在哪里? – Trap

1

我看到它的方式,视图模型旨在扩展您的模型以迎合您的用户界面,而不会让您丑陋起来模型与一堆UI特定的代码。如果你的模型按照定义被设计为用于UI构建的对象,那么它确实满足模型和视图模型的角色,并且没有意义为设计添加另一层。

1

我总是理解你的模型只是数据,就是这样。没有方法或类似的东西(我甚至没有在我的模型中实现INPC)

您的视图模型的目的是以友好的方式向您的视图呈现数据。所以你不应该直接绑定到模型数据,而是永远绑定到视图模型上的数据。

我所做的就是让我的模型,让我们说模型是一个Person类,它只是保存这些值而已,如果我想用这个类来绑定,那么我会创建它的一个实例在我的模型上。但是,如果需要INotifyPropertyChanged,我会创建一个DVM(数据视图模型),它包含Person类的一个实例,并具有用于在person类中获取/设置数据的属性,但也会在需要时引发INPC。这个类还将包含我可能需要的任何UI特定数据。

所以我实现MVVM的样子

型号> DVM(可选)>视图模型>查看

的观点从来没有直接,只能通过视图模型谈判模型。

我也觉得后面的代码应该尽量避免使用一个好的MVVM实现。

在回答你的问题是MVVM需要?可能不是,但做得很好我发现一个MVVM应用程序非常容易理解和维护。

我认为你在MVVM方面的问题可能就是你接近设计的方式。我总是在创建视图的同时创建空视图模型类,这样看起来并不是什么大事。

相关问题