從Prism中學習設計模式之MVVM 模式(一)--簡述MVVM


在學習Prism中涉及的MVVM之前,我想有必要分別把MVC&MVP,MVVM,Command三種模式進行簡單的總結,這樣可以更好的理解Prism尤其是WPF的設計理念。

本文內容:

  • MVVM的來龍去脈
  • 為什么Prism使用MVVM
  • 示例講解

一、MVVM的來龍去脈

     在我們開發具有UI界面的應用程序時,MVC和MVP模式會被大量的采用,應用這些模式可以很容易的開發各類應用程序。隨着WPF的普及,一種基於MVC&MVP模式的變種,MVVM模式被微軟的p&p小組提出。通過頁面,數據源,邏輯分離,MVVM使開發工作更容易分工,程序結構更清晰和易維護。

  MVVM全稱Model/View/ViewModel。

      Model即數據模型,可以是Json,數據庫表內容,對象,XML,文本文件,本地儲存內容等等等等。

  View即視圖也是UI,提供給最終用戶交互界面,對於View來說Model是什么,並不關心,二者之間不需要聯系。

      ViewModel即視圖模型,負責為View所需呈現的數據提供數據源,為View的交互操作提供業務邏輯的支持。

二、為什么Prism使用MVVM

  輕量級框架Prism通過應用MVVM,使開發團隊專注於業務邏輯的開發,設計團隊專注於為用戶設計友好的交互界面,兩個團隊經可能小的涉及交叉設計開發。為了實現以上功能和發揮WPF的優勢,Prism使用了多種設計模式進行功能的擴展。如通過Command模式設計擴展了中繼命令邏輯,提供了AttachBehaiverCommand,DelegateCommand等。Lz以后會詳細進行說明。

三、示例講解

  以下是一個非常Simple的MVVM Demo。場景:一個相冊界面

  1.顯示相冊列表

      2.點擊相冊列表中某一相冊

      3.跳轉事件觸發

      4.跳轉至某一相冊

      5.圖片列表加載

  Demo 設計了數據類Album,用戶UI AlbumView,視圖模型AlbumViewModel,AlbumViewModel 提供跳轉函數並實現ICommand接口,AlbumView觸發Command執行AlbumViewModel的跳轉函數。

  Model:

 1 namespace SimpleMVVMApp.Business.Model {
 2     public class Album : INotifyPropertyChanged {
 3         public event PropertyChangedEventHandler PropertyChanged;
 4 
 5         public string Name {
 6             get {
 7                 return this.name;
 8             }
 9             set {
10                 if (value != this.name) {
11                     this.name = value;
12                     if (this.PropertyChanged != null) {
13                         this.PropertyChanged(this, new PropertyChangedEventArgs("Name"));
14                     }
15                 }
16             }
17         }
18 
19         public string Path { get; set; }
20 
21         public string Border {
22             get {
23                 return this.border;
24             }
25             set {
26                 if (value != this.border) {
27                     this.border = value;
28                     if(this.PropertyChanged != null){
29                         this.PropertyChanged(this,new PropertyChangedEventArgs("Border"));
30                     }
31                 }
32             }
33         }
34 
35         private string name;
36         private string border;
37     }
38 }

  ViewModel:

 1     public class AlbumViewModel {
 2         public Album Album {
 3             get {
 4                 return this.album;
 5             }
 6         }
 7 
 8         public IEnumerable<string> Borders { get; private set; }
 9 
10         public ICommand RediectCommand { get; private set; }
11 
12         public AlbumViewModel() {
13             this.album = new Album { Name = "MVVM" };
14             this.RediectCommand = new RelayCommand((o) => this.OnRediect(o));
15         }
16 
17         private void OnRediect(object args) {
18             this.album.Name = "Command";
19             //Todo Get Photo List and Rediect to page
20         }
21 
22         private readonly Album album;
23     }

  View:

 1 <UserControl x:Class="SimpleMVVMApp.View.AblumView"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:vm="clr-namespace:SimpleMVVMApp.Business.ViewModel"
 7              mc:Ignorable="d" 
 8              d:DesignHeight="300" d:DesignWidth="300">
 9     <UserControl.DataContext>
10         <vm:AlbumViewModel/>
11     </UserControl.DataContext>
12     <Grid>
13         <Button Command="{Binding RediectCommand}" Content="{Binding Album.Name}"></Button>
14     </Grid>
15 </UserControl>

  由於良好的顯示效果不是本文的主題,LZ就簡單了用了一個Button來表示UI,如果需要良好的顯示交互效果,可以通過重寫Visual Template或者另寫一個Visual類來實現更好的顯示效果。

  圖1,點擊前效果,圖2,通過Command執行函數后效果:

  

                    圖1                                    圖2

 源代碼下載:http://files.cnblogs.com/tmywu/SimpleMVVMApp.7z

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM