我想知道为什么我们应该使用MVVM来实现Silverlight应用程序。它有什么优势?
我们不对ViewModel进行单元测试,所以我还有其他原因。
以下是我对人们通常所说的一些好处的疑问:
1.Loosely Coupled:当我们使用MVVM时,视图依赖于ViewModel而不是视图,为什么它会松散耦合?
2.如果我在代码隐藏中提供公共方法,它们也可以提供可重用性。
答案 0 :(得分:4)
嗯,视图模型的单元可测试性是一个显着的优势,所以你会错过这个好处。关于其他两个:
松散耦合
是的,视图确实依赖于视图模型。它们必须以某种方式连接以完成应用程序的功能。结果,他们不能脱钩。唯一的选择是紧耦合或松散耦合或介于两者之间。使用MVVM,您的视图模型以非常有限的方式与您的视图交互:基本上只是对象,属性和命令。将此与代码隐藏中的所有内容进行比较,其中视图及其控件基本上是不可分割的。
<强>重新使用强>
如果代码隐藏中的任何代码可以重复使用以便公开,那么可以将其从代码隐藏中删除并放入通用类中。问题是之后剩下的是不可重用的。
如果你不想深入研究MVVM,那么你可以通过专注于数据绑定来获得MVVM的一些好处。在了解了数据绑定的好处之后,您可以重新考虑MVVM的其他好处。
答案 1 :(得分:4)
我们不对ViewModel进行单元测试,
使用MVVM,它不仅仅是单元测试ViewModel。理想情况下,您的VM应该非常精简,并且只具有视图所需的属性。因此,没有必要测试VM。
但是,如果没有VM,您如何跨层进行功能/功能测试?在Silverlight中,为了便于测试,您应该使用命令,而不是在代码隐藏文件中编写代码。这允许您在单元测试时模拟按钮单击和其他GUI事件。使用MVVM模式和命令,您可以测试所有C#代码(不是xaml),直到UI(转换器,VM等)。
如果我提供公共方法 代码隐藏,他们也可以提供 可重用性。
不详细说明这是一个糟糕的设计,我想问你,这如何提供重复性?如果你创建一个用户控件,那么代码隐藏类是一个控件?您想要创建控件的实例并使用它们吗?这就像说我们为什么需要成员方法,我们可以创建公共静态方法并访问它们。我强烈认为,如果我们不想使用WPF / Silverlight提供的自动绑定,那么最好不要使用这些技术。为了充分利用绑定的全部功能,MVVM至关重要。
为什么它松散耦合?
VM是您视图的重要组成部分。它没有脱离视图。正如我所说,您的VM应该尽可能薄,只需要您的视图所需的公共属性。您的业务逻辑将与您的视图(和VM)分离。
答案 2 :(得分:1)
我认为这是最好的资源之一,如果你想使用和对比MVVM的使用与任何其他模式或没有模式。
http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/
答案 3 :(得分:1)
我可以回答我如何使用MVVM模式。 MVVM在以下场景中更好:
1如果多个控件与单个属性绑定。
MVVM:
<TextBlock x:Name="text1" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>
<TextBlock x:Name="text2" Visibility="{Binding IsSomePropertyTrue, Converter={StaticResource VisibilityConverter}"/>
我可以快速添加类似控件或删除现有控件。
与代码隐藏相比较:
public string IsSomePropertyTrue
{
set
{
//...
text1.Visibility = value;
text2.Visibility = value;
}
}
2而不是多转换器
public Brush StateColor { 得到 { if(this.State == State.Edited&amp;&amp; this.IsPriority) 返回新的SolidColorBrush(Color.FromArgb(255,0,255,0)); // ... } }
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="{Binding StateColor}" Text="{Binding State}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
3作为ListBox或DataGrid等控件中的项模型。例如,如果我想在每个项目附近创建一个带有删除按钮的项目列表,我将创建一个ItemView控件和一个ItemViewModel类。
<ItemsControl ItemsSource="{Binding SomeItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<view:ItemView DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
4将数据从一个视图复制到另一个视图:
public JournalEntryViewModel(SalesOrderViewModel vm) {}
5 ViewModel可以继承CLR类并实现接口(INotifyPropertyChanged或INotifyDataErrorInfo)。
我还使用MVVM用命令或属性替换事件。并使用ViewModel强制通过可理解的名称调用属性。
答案 4 :(得分:1)
我是WPF的早期采用者,我可以告诉你是什么让我选择了MVVM(这或多或少也适用于Silverlight)。对于我正在进行的项目,我必须创建一个允许用户订阅系统内通知的屏幕。这是一个3步骤的过程:
第一次实现功能(没有MVVM)后,我被告知我们需要从已经订阅的搜索项中排除。
完成修复后,我被告知我们需要根据选项为用户提供订阅的实时预览。
到那时,我开始注意到,如果我在更改逻辑时不必处理操作UI,那么可以提取一些这些更改并使其更容易。我从未故意跟随MVVM,但我意识到我所做的抽象与MVVM模式非常匹配。
所以这就是我推荐这种模式的原因。它通过将UI与UI本身分开来简化更改驱动UI的逻辑的任务。我还建议您在需要之前暂停实施。使用MVVM需要付出代价,但它会因更改UI逻辑的成本而摊销。
答案 5 :(得分:1)
如果没有MVVM,您的Silverlight应用程序代码很快就会变成难以管理的混乱
答案 6 :(得分:0)
MVVM中有趣的还有动态自动绑定。
想象一下,您的视图模型具有以下属性:bool IsFirstNameVisible,bool IsFirstNameEnabled,string FirstName,double FirstNameWidth等。
在XAML文件中,使用x:Name =“FirstName”定义TextBox并调用动态MVVM-binder。它通过反射检查您的视图模型类,查看您定义的属性,并将它们动态绑定到具有相同名称的控件的类似属性,并在需要时应用值转换器。
在这种情况下,你得到非常干净的XAML,没有千米长的数据绑定表达式和转换器。
这就是我的MVVM库。
答案 7 :(得分:0)
Conerns人的分离。关注点分离。
忘记单元测试(我喜欢它;但这不是这里的事情)。忘记可重用性(你真的重新使用视图模型吗?不,让我们在这里真实)。
关于分离关注并将代码和逻辑放在它所属的位置。整个想法是可维护性;能够随着时间的推移对代码进行更改,而不会破坏其他东西,也不会将整个事物变成一大堆意大利面。
MVVM,正确完成后,可以将您的代码分成合理的逻辑部分,并在应用程序的需求发生变化时允许重新进行重构和更改。当您需要进行更改时,更容易找到 某些内容。尝试编写任何中途复杂的应用程序,然后将其单独搁置一个月,然后回到它并尝试进行重大更改。明智地使用MVVM的结构合理的应用程序在裁员后更容易理解,并且更容易进行更改。