模型檢視 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>