模型视图 ViewModel(MVVM)
1.什么是 MVVM?
模型视图 ViewModel(MVVM)
模式是最常用于创建用户界面的设计模式。它源于流行的模型视图控制器(MVC)模式。MVVM 的主要优点是它分离:
- 应用程序状态的内部表示(模型)。
- 信息如何呈现给用户(视图)。
- 值转换器逻辑负责从模型中公开和转换数据,以便可以在视图(ViewModel)中轻松管理和显示数据。
2. MVVM 的使用案例
MVVM 的主要用例是图形用户界面(GUI)编程。它通过将视图层与管理数据的后端逻辑分开来用于简单的事件驱动的用户界面编程。
例如,在 Windows Presentation Foundation(WPF)
中,视图是使用框架标记语言 XAML 设计的。XAML 文件使用数据绑定绑定到 ViewModels。这样,视图仅负责表示,viewmodel 仅负责通过处理模型中的数据来管理应用程序状态。
它也用在 JavaScript 库 KnockoutJS 中。
3.实施
考虑使用 C#.Net 和 WPF 的 MVVM 的以下实现。我们有一个名为 Animals 的 Model 类,一个在 Xaml 中实现的 View 类和一个名为 AnimalViewModel 的 ViewModel。下面的示例是来自 Design Patterns - MVC Pattern 的 MVC 教程的修改版本。
看看 Model 不知道任何事情,ViewModel 只知道 Model,而 View 只知道 ViewModel。
OnNotifyPropertyChanged 事件可以更新模型和视图,以便在视图的文本框中输入内容时,模型会更新。如果某些内容更新了模型,则会更新视图。
/*Model class*/
public class Animal
{
public string Name { get; set; }
public string Gender { get; set; }
}
/*ViewModel class*/
public class AnimalViewModel : INotifyPropertyChanged
{
private Animal _model;
public AnimalViewModel()
{
_model = new Animal {Name = "Cat", Gender = "Male"};
}
public string AnimalName
{
get { return _model.Name; }
set
{
_model.Name = value;
OnPropertyChanged("AnimalName");
}
}
public string AnimalGender
{
get { return _model.Gender; }
set
{
_model.Gender = value;
OnPropertyChanged("AnimalGender");
}
}
//Event binds view to ViewModel.
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
var e = new PropertyChangedEventArgs(propertyName);
this.PropertyChanged(this, e);
}
}
}
<!-- Xaml View -->
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:viewModel="clr-namespace:WpfApplication6">
<Window.DataContext>
<viewModel:AnimalViewModel/>
</Window.DataContext>
<StackPanel>
<TextBox Text="{Binding AnimalName}" Width="120" />
<TextBox Text="{Binding AnimalGender}" Width="120" />
</StackPanel>
</Window>