Prism安装、MVVM基础概念及一个简单的样例
一:Prism的下載和安裝
1:在http://compositewpf.codeplex.com/上下載最新的包。
下載完畢后,運行之,選擇解壓目錄解壓之。解壓完畢的根目錄下有chm幫助文檔。
2:運行RegisterPrismBinaries.bat注冊Prism組件,注冊完畢才能在VS的引用中直接找到Prism組件,否則需要手動添加這些組件。
3:運行Silverlight Only - Basic MVVM QuickStart.bat可以打開一個MVVM的簡單事例。
二:MVVM理解
1:現(xiàn)在,我們自己創(chuàng)建一個普通的SilverLight樣例,并且將它逐步重構(gòu)成為MVVM模式。
這個 普通的SL樣例需求有:在界面上放置文本框用來顯示Name和Button用來顯示文本框中的Name的值。
前臺:
后臺:
SL的目錄結(jié)構(gòu):
2:問題來了
如果我們需要讓頁面的值和Student實例的值保持一致,則必須要讓類型繼承自INotifyPropertyChanged接口,并像下面這樣編碼:
public class Student : INotifyPropertyChanged{string firstName;public string FirstName {get { return firstName;}set {firstName = value; Notify("FirstName"); }}string lastName;public string LastName { get {return lastName;}set { lastName = value;Notify("LastName");}}public Student(string firstName, string lastName){this.firstName = firstName;this.lastName = lastName;}void Notify(string propName){if (PropertyChanged != null){PropertyChanged(this, new PropertyChangedEventArgs(propName));}}#region INotifyPropertyChanged Memberspublic event PropertyChangedEventHandler PropertyChanged;#endregion}如果應(yīng)用程序中存在多個這樣的類型,則每個類型都要實現(xiàn)自己的Notify方法,這顯然是不合理的。所以,無論是Prism框架,還是輕量級的Mvvm light toolkit,都實現(xiàn)了一個超類來包裝這種需求,在Prism里該超類是NotificationObject,而Mvvm light toolkit中是ObservableObject,當(dāng)然,毫無例外滴,它們都繼承自INotifyPropertyChanged。
3:現(xiàn)在,我們參照這兩個類型,來實現(xiàn)自己的NotificationObject,以便加深印象
public abstract class NotificationObject : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;protected virtual void RaisePropertyChanged(string propertyName){PropertyChangedEventHandler handler = this.PropertyChanged;if (handler != null){handler(this, new PropertyChangedEventArgs(propertyName));}}protected void RaisePropertyChanged(params string[] propertyNames){if (propertyNames == null) throw new ArgumentNullException("propertyNames");foreach (var name in propertyNames){this.RaisePropertyChanged(name);}}protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression){var propertyName = ExtractPropertyName(propertyExpression);this.RaisePropertyChanged(propertyName);}public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression){if (propertyExpression == null){throw new ArgumentNullException("propertyExpression");}var memberExpression = propertyExpression.Body as MemberExpression;if (memberExpression == null){throw new ArgumentException("PropertySupport_NotMemberAccessExpression_Exception", "propertyExpression");}var property = memberExpression.Member as PropertyInfo;if (property == null){throw new ArgumentException("PropertySupport_ExpressionNotProperty_Exception", "propertyExpression");}var getMethod = property.GetGetMethod(true);if (getMethod.IsStatic){throw new ArgumentException("PropertySupport_StaticExpression_Exception", "propertyExpression");}return memberExpression.Member.Name;}}相應(yīng)的,Student類型修改為:
public class Student : NotificationObject{string firstName;public string FirstName {get { return firstName;}set {firstName = value; //Notify("FirstName"); this.RaisePropertyChanged("FirstName");}}string lastName;public string LastName { get {return lastName;}set { lastName = value;//Notify("LastName");this.RaisePropertyChanged("LastName");}}public Student(string firstName, string lastName){this.firstName = firstName;this.lastName = lastName;}}4:問題再次出現(xiàn),經(jīng)過修改后的Student類型,是什么?
是實體Model,領(lǐng)域Model,還是別的什么?實際上,因為沒有采用任何架構(gòu)模式,當(dāng)前的Student類型什么也不是,揉雜了很多功能。它既要負責(zé)提供屬性,也要負責(zé)控制。
在MVVM架構(gòu)模式中,和MVC稱謂不同的地方,就是VM(ViewModel)部分。VM負責(zé):接受View請求并決定調(diào)用哪個模型構(gòu)件去處理請求,同時它還負責(zé)將數(shù)據(jù)返回給View進行顯示。也就是說,VM完成的角色可以理解為MVC中的Control。(另外需要注意的一點是,在MVC中有一個概念叫做表現(xiàn)模型,所謂表現(xiàn)模型是領(lǐng)域模型的一個扁平化投影,不應(yīng)和MVVM中的VIEW MODEL相混淆)。
所以,我們現(xiàn)在要明確這些概念。首先,將Student類型的功能細分化,VM的部分,我們跟頁面名稱對應(yīng)起來應(yīng)該叫做MainViewModel。實際項目中,功能頁面會相應(yīng)名為StudentView.xaml,則對應(yīng)的VM名便稱之為StudentViewModel.cs。我們繼續(xù)重構(gòu)上面的代碼。
三:建立MVVM的各個部分
首先,建立View文件夾,然后,將MainPage.xmal修改為StudentView.xaml后放置到該目錄下。
其次,簡歷ViewModels文件夾,新建一個類StudentViewModel.cs,放置到該目錄下。
最后,原類型Student需要繼續(xù)拆分,將作為領(lǐng)域模型部分的功能獨立出來,放置到DomainModel文件夾下。最后的結(jié)果看起來如下:
1:領(lǐng)域模型DomainModel部分
public class Student {string firstName;public string FirstName{get{return firstName;}set{firstName = value;}}string lastName;public string LastName{get{return lastName;}set{lastName = value;}}public Student(){//模擬獲取數(shù)據(jù)Mock();}public void Mock(){FirstName = "firstName" + DateTime.Now.ToString();LastName = "lastName" + DateTime.Now.ToString();}}2:視圖View部分
3:ViewModel部分
public class StudentViewModel : NotificationObject{public StudentViewModel(){student = new Student();}Student student;public Student Student {get{return this.student;}private set{this.student = value;this.RaisePropertyChanged(() => this.student);}}}4:若干解釋
在這個簡單的事例中,領(lǐng)域模型Student負責(zé)獲取數(shù)據(jù),而數(shù)據(jù)來源于何處不是我們關(guān)心的重點,所以,我們直接在Student中模擬了獲取數(shù)據(jù)的過程,即Mock方法。
這相當(dāng)于完成了一次OneWay的過程,即把后臺數(shù)據(jù)推送到前臺進行顯示。這只能算是完成跟UI交互的一部分功能。UI交互還需要包括從UI中將數(shù)據(jù)持久化(如保存到數(shù)據(jù)庫)。而UI跟后臺的交互,就需要通過命令綁定的機制去實現(xiàn)了。
5:命令綁定
在本里中,我們演示兩類命令,一類是屬性類命令綁定,一類是事件類命令綁定。
首先,我們知道,VM負責(zé)UI和領(lǐng)域模型的聯(lián)系,所以,綁定所支持的方法一定是在VM中,于是,我們在StudentViewModel中定義一個屬性CanSubmit,及一個方法Submit:
public bool CanSubmit{get{return true;}}public void Submit(){student.Mock();??????? }注意,Submit方法中為了簡單期間,使用了模擬方法。由于Mock方法中仍然可能設(shè)計到UI的變動(如隨數(shù)據(jù)庫的某些具體的值變動而變動),故領(lǐng)域模型Student可能也會需要繼承NotificationObject,在本例中,Student改變?yōu)槿缦?#xff1a;
public class Student : NotificationObject{string firstName;public string FirstName{get{return firstName;}set{firstName = value;this.RaisePropertyChanged("FirstName");}}string lastName;public string LastName{get{return lastName;}set{lastName = value;this.RaisePropertyChanged("LastName");}}public Student(){//模擬獲取數(shù)據(jù)Mock();}public void Mock(){FirstName = "firstName" + DateTime.Now.ToString();LastName = "lastName" + DateTime.Now.ToString();}}其次,需要改變VIEW,如下:
注意途中紅線框起來的部分。
經(jīng)過這一次的重構(gòu)之后,基本滿足了一個簡單的MVVM模型的需要。代碼下載在這里:http://files.cnblogs.com/luminji/SilverlightApplication2.rar
微信掃一掃,關(guān)注最課程(www.zuikc.com),獲取更多我的文章,獲取軟件開發(fā)每日一練
下一篇講述使用Prism的MVVM框架
總結(jié)
以上是生活随笔為你收集整理的Prism安装、MVVM基础概念及一个简单的样例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对QT学习之路12-14的源代码补充与修
- 下一篇: 推荐15个在线多媒体(图片、音频、视频)