MVVM即Model-View-ViewModel,MVVM模式與MVP(Model-View-Presenter)模式相似,主要目的是分離視圖(View)和模型(Model),具有低耦合、可重用性、獨立開發、可測試性等優點。
MVVM框架有很多,開源的主要有:
- PRISM:由微軟提供,和MEF/Unity一起用於依賴注入,支持組合命令,可以擴展。MSDN上有詳細的教程和演練。
- MVVM Light Toolkit:有visual Studio和Expression Blend的項目和項的模板。更多信息請看這里,另外可以參考VS和Expression Blend的使用教程。
- Caliburn Micro:支持視圖模型先行(ViewModel-First)和視圖先行(View-First)兩種開發方式,通過co-routine支持異步編程。
- Simple MVVM Toolkit:提供VS項目和項的模板,依賴注入,支持深拷貝以及模型和視圖模型之間的屬性關聯。
- Catel:包含項目和項的模板,用戶控件和企業類庫。支持動態視圖模型注入,視圖模型的延遲加載和驗證。還支持WP7專用的視圖模型服務。
閉源框架主要有:
- Intersoft ClientUI:付費的,只支持WPF和Silverlight,但是,除了MVVM框架,它還提供其它一些特性。
- Vidyano:免費但不開源。帶有實體映射/虛擬持久化對象(數據容器),業務規則以及內置基於ACL的安全特性。
今天我使用的是微軟提供的Prism4.1搭建的小測試。
首先建了個WPF項目,項目目錄結構如圖
Models 存放的是數據模型
Service存放的是業務邏輯
ViewModels存放的便是視圖模型
Views存放WPF窗口
在Models文件夾中創建一個用戶模型User.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test.Wpf.Mvvm.Models { class User { /// <summary> /// 用戶名 /// </summary> public string Nameword { get; set; } /// <summary> /// 密碼 /// </summary> public string Password { get; set; } } }
在Services文件夾中添加用戶的業務邏輯UserService.cs,因為自己寫這個程序重點是學習MVVM,所以這里就簡單寫了一下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test.Wpf.Mvvm.Services { class UserService { /// <summary> /// 獲取所有用戶方法 /// </summary> /// <returns></returns> public List<Models.User> GetAllUser() { List<Models.User> users = new List<Models.User>(); for (int i = 0; i < 3; i++) { Models.User user = new Models.User(); user.Nameword = "用戶" + i; user.Password = "密碼" + i; users.Add(user); } return users; } } }
在ViewModels中創建主窗口的視圖模型MainWindowViewModel.cs,這個地方要添加引用Microsoft.Practices.Prism.dll,我把它放在libs中了
//*************************************************** // // 文件名(FileName) : MainWindowViewModel.cs // // 作者(Author) : zsm // // 創建時間(CreateAt): 2013-09-03 16:17:29 // // 描述(Description) : 主窗口ViewModel // //*************************************************** using Microsoft.Practices.Prism.Commands; using Microsoft.Practices.Prism.ViewModel; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Test.Wpf.Mvvm.ViewModels { class MainWindowViewModel : NotificationObject { /// <summary> /// 用戶List /// </summary> private List<Models.User> users; public List<Models.User> Users { get { return users; } set { users = value; RaisePropertyChanged("Users"); } } /// <summary> /// 程序名 /// </summary> public string AppName { get; set; } /// <summary> /// 電話 /// </summary> private string phone; public string Phone { get { return phone; } set { phone = value; RaisePropertyChanged("Phone"); } } /// <summary> /// 獲取所有用戶命令 /// </summary> public DelegateCommand GetAllUsersCommand { get; set; } /// <summary> /// 構造初始化 /// </summary> public MainWindowViewModel() { AppName = "WPF MVVM 模式測試"; Phone = "123456"; GetAllUsersCommand = new DelegateCommand(new Action(GetAllUsersCommandExecute)); } /// <summary> /// 獲取所有用戶命令執行方法 /// </summary> private void GetAllUsersCommandExecute() { Phone = Phone.Equals("123456") ? "1234567" : "123456"; Services.UserService userService = new Services.UserService(); Users = userService.GetAllUser(); } } }
MainWindow.xaml頁面的設計是
<Window x:Class="Test.Wpf.Mvvm.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"> <Grid> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <Label Content="程序名"></Label> <Label Content="{Binding AppName}"></Label> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Content="電話"></Label> <Label Content="{Binding Phone}"></Label> </StackPanel> <StackPanel> <Button Content="獲取所有用戶" Command="{Binding GetAllUsersCommand}"></Button> </StackPanel> <DataGrid ItemsSource="{Binding Users}" AutoGenerateColumns="False" GridLinesVisibility="All" CanUserDeleteRows="False" CanUserAddRows="False" > <DataGrid.Columns> <DataGridTextColumn Header="用戶名" Binding="{Binding Nameword}"></DataGridTextColumn> <DataGridTextColumn Header="密碼" Binding="{Binding Password}"></DataGridTextColumn> </DataGrid.Columns> </DataGrid> </StackPanel> </Grid> </Window>
然后在MainWindow的交互代碼中綁定ViewModel
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Test.Wpf.Mvvm { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new ViewModels.MainWindowViewModel();//綁定ViewModel
} } }
運行一下就可以了
同步個人網站地址http://blog.zhangshimin.com.cn/?p=35
