概述
MVC的概念已经逐渐被大家所熟悉——Model,View,Controllor。但是在最近的开发过程中,特别与WPF相关的开发中,发现MVVM这个模式相当好用,而且还可以很方便的通过UnitTest了检查UI的错误。
什么是MVVM呢,就是Model,View,ViewModel。
- Model就是对数据的抽象,数据的封装。比如,Person。
- View就是UI表现层,提供与终端用户的交互。比如,一个用户录用界面。
- ViewModel是这种模式的核心,提供了一个Model与View之间的桥梁。它应该提供了View中所有用户可能的操作对应的处理,以及该处理能去Model进行必要的操作,或者缓存该处理结果,等待下次使用。
让我们举的例子。
Case 1:我们有一个Person的Model和一个选择Person的界面。那么,我们需要一个IsSelected的属性来标记用户的选择。但是把IsSelected属性放入Person类肯定是不合适的,而且可能你根本就没有权力可以修改Person类。所以我们建立一个PersonViewModel的类,里面有Person类的对象,并提供IsSelected属性。这样View就可以对PersonViewModel直接操作,如果是WPF的话,就可以直接绑定了。
Case 2:让我们在Case1的基础上给View加一些功能,有一个Enroll的按钮,如果用户点击,那么被选中的Person就会被录用。那么这个时候,我们就需要在PersonViewModel里面再增加一个Enroll的方法,在该方法里去操作Person的Enrollment的一些信息。
Case 3:我们还需要告诉View,被录用的Person的录用信息。那么我们在PersonViewModel中增加一个Enrollment的属性,当被Enroll的时候,通知Enrollment属性被改变了,View就能更新数据了。
为什么用MVVM模式?
一是为了把View层的逻辑抽象到了VIewModel中,又保持了Model的数据独立性。可以把ViewModel层当成逻辑的抽象,但是应该同时包括业务逻辑和页面逻辑。
二是为了方便我们测试代码,以前对含有UI的测试,Unit Test是不够的,但是因为有了VIewModel这层,我们可以通过ViewModel来模拟用户的操作。
这个模式的确是一个很适合WPF的开发的模式。
Example Code:
Person.cs
public class Person
{
public string Name { get; set; }
public string Company { get; set; }
public string EnrolledBy { get; set; }
public DateTime EnrollDate { get; set; }
}
public sealed class PersonViewModel : INotifyPropertyChanged
{
public Person MyPerson { get; set; }
public PersonViewModel(Person person)
{
this.MyPerson = person;
}
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
if (isSelected != value)
{
isSelected = value;
PropertyChange("IsSelected");
}
}
}
public string Enrollment
{
get
{
if (string.IsNullOrWhiteSpace(MyPerson.Company))
{
return string.Empty;
}
return string.Format("Company {0} enrolled this guy at {1}.", MyPerson.Company, MyPerson.EnrollDate);
}
}
public void Enroll(string companyName, string enrollBy)
{
MyPerson.Company = companyName;
MyPerson.EnrolledBy = enrollBy;
MyPerson.EnrollDate = DateTime.Now;
PropertyChange("Enrollment");
}
private void PropertyChange(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Main"
Title="MainWindow" Height="350" Width="525">
<Grid>
<CheckBox Content="" Height="16" HorizontalAlignment="Left" Margin="42,33,0,0" Name="checkBox1" VerticalAlignment="Top" IsChecked="{Binding Path=Person.IsSelected, Mode=TwoWay, ElementName=Main}"/>
<TextBlock Height="23" HorizontalAlignment="Left" Margin="79,33,0,0" Name="textBlock1" VerticalAlignment="Top" Width="210" Text="{Binding Path=Person.MyPerson.Name, ElementName=Main}" />
<Button Content="Enroll" Height="23" HorizontalAlignment="Left" Margin="79,79,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="306,33,0,0" Name="textBlock2" VerticalAlignment="Top" Width="146" Text="{Binding Path=Person.Enrollment, ElementName=Main}" />
</Grid>
</Window>
MainWindow.xaml.cs
public PersonViewModel Person
{
get { return (PersonViewModel)GetValue(PersonProperty); }
set { SetValue(PersonProperty, value); }
}
// Using a DependencyProperty as the backing store for Person. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PersonProperty =
DependencyProperty.Register("Person", typeof(PersonViewModel), typeof(MainWindow));
public MainWindow()
{
InitializeComponent();
Person = new PersonViewModel(new Person() { Name = "John" });
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Person.Enroll("Microsoft", "Microsoft HR");
}
最后
以上就是伶俐战斗机为你收集整理的MVVM模式--Model,View,ViewModel三者平衡的全部内容,希望文章能够帮你解决MVVM模式--Model,View,ViewModel三者平衡所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复