uwp開發(fā):MVVM模式和數(shù)據(jù)綁定結(jié)合使用實戰(zhàn)示例

——我的《簡影uwp》開發(fā)了一段時間了,現(xiàn)在各個板塊和基本功能已經(jīng)完工,剩下的就是細(xì)節(jié)方面的處理和UI排版設(shè)計了。開發(fā)期間遇到過很多問題,由于是個人獨立開發(fā)。所以好多問題需要自己想好長時間,或者去網(wǎng)上尋找大神求助,有時候晚上做夢都是滿腦子的代碼。好的是大部分最終都解決了!真的非常感謝那些幫助我的大神們,和他們交流,我學(xué)到了很多。。。

好了,閑話不多說,前幾天,我處理的是集合數(shù)據(jù)綁定的問題,也就是說返回的是一個集合數(shù)據(jù),用MVVM模式來說,讓ViewModel層實現(xiàn)ObservableCollection接口,并且在ViewModel里將獲取到的list數(shù)據(jù)集合采取遍歷集合并添加進ObservableCollection集合里,這樣,在View層的后臺,只需實例化ViewModel,并綁定到界面上,這樣就實現(xiàn)了集合綁定及更改通知。

今天要說的是MVVM模式中處理非集合數(shù)據(jù)對象的綁定,這樣的話,當(dāng)然是要讓ViewModel 實現(xiàn)INotifyPropertyChanged接口了。

1、Model類如下:

public? class TCContent

? ? {

? ? ? ? public string Image { get; set; }

? ? ? ? public string Title { get; set; }

? ? ? ? public string Directors { get; set; }

? ? ? ? public string Casts { get; set; }

? ? ? ? public string Pubdate { get; set; }

? ? ? ? public string TrailerUrl { get; set; }

? ? ? ? public string ItemSummary { get; set; }

? ? }

2、在ViewModel中,該怎么寫呢?

因為INotifyPropertyChanged接口,它通知的對象是屬性。所以,怎樣才能通知到Modle中的每個屬性呢?總不能把Model類的所有屬性都寫一遍再通知吧?當(dāng)然不是了,其實很簡單,就是將Model作為ViewModel的一個屬性。

為了代碼簡潔,重用方便,定義個ViewModelBase的類,讓它來實現(xiàn)INotifyPropertyChanged接口,完成相關(guān)通知。最后讓ViewModel繼承它就可以了。

這個BaseModel類如下:注意,我這里寫出了實現(xiàn)屬性更改通知的兩種方法,早期一般用的是第二種,也很容易理解,在ViewModel的屬性的set方法里,調(diào)用該方法即可,括號內(nèi)傳入的是屬性名。這種方法容易看懂,但是缺點也很明顯,就是屬性名容易寫錯。

而第一種方法是推薦使用的,這里用到了CallerMeberName這個特性,具體可以查msdn文檔,就是說系統(tǒng)內(nèi)部通過反射可以自動獲取屬性名,這樣的話,我們在ViewModel類的屬性的set方法里就不用再寫屬性名了,很方便。我這里用方法一示例。

?ViewModleBase類:

public class ViewModelBase : INotifyPropertyChanged

? ? {

? ? ? ? public event PropertyChangedEventHandler PropertyChanged;

? ? ? ? //方法一:CallerMemberName 特性可以獲取到 成員

? ? ? ? public void MyPropertyChanged([CallerMemberName]string propertyName = "")

? ? ? ? {

? ? ? ? ? ? PropertyChangedEventHandler handler = PropertyChanged;

? ? ? ? ? ? if (handler != null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? handler.Invoke(this, new PropertyChangedEventArgs(propertyName));

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? ////方法2:

? ? ? ? //public void OnPropertyChanged(string propertyName)

? ? ? ? //{

? ? ? ? //? ? PropertyChangedEventHandler handler = this.PropertyChanged;

? ? ? ? //? ? if (handler != null)

? ? ? ? //? ? {

? ? ? ? //? ? ? ? handler.Invoke(this, new PropertyChangedEventArgs(propertyName));

? ? ? ? //? ? }

? ? ? ? //}

? ? }

3、下來是

ViewModel類如下:這里把Model類作為一個屬性,同時繼承自剛才實現(xiàn)的ViewModel基類。這樣,只需要在ViewModel里實現(xiàn)MyPropertyChanged方法即可。而且因為在ViewModelBase中用的是第一種方法,可以直接獲取到屬性名,所以只需寫出該方法即可!

public class TCContentViewModel :ViewModelBase? ? {? ? ? ? private TCContent _tcContent;? ? ? ? public TCContent TcContent? ? ? ? {? ? ? ? ? ? get { return _tcContent; }? ? ? ? ? ? set? ? ? ? ? ? {? ? ? ? ? ? ? ? _tcContent = value; MyPropertyChanged();}? ? ? ? }? ? }

4、下來,就是View層了,在view層界面需要的是展示Modle里的屬性。

在View后臺: 在外部聲明 ViewModel的對象 tvm,然后在構(gòu)造函數(shù)里實例化即可。

? ? ? ? private TCContentViewModel tvm;

? ? ? ? public TCContentView()

? ? ? ? {

? ? ? ? ? ? this.InitializeComponent();

? ? ? ? ? ? tvm = new TCContentViewModel();


? ? ? ? }

? ? ? ? protected override async void OnNavigatedTo(NavigationEventArgs e)

? ? ? ? {

? ? ? ? ? ? base.OnNavigatedTo(e);

? ? ? ? ? ? if (e.Parameter != null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? tvm.TcContent = await NetService.TCNetservice.GetTCContent((e.Parameter as TC).Tid);

? ? ? ? ? ? }

? ? ? ? }

5、最后一步:

在View前臺界面:截取部分如下:

每個要顯示的元素綁定到ViewModel實例化的對象 tvm 上的TcContent屬性的屬性上,因為TcContent這個屬性才是我們要顯示的元素對應(yīng)的Model,而我們需要的就是Model里面的屬性,所以繼續(xù)點屬性即可。綁定的時候,是可以一直點下去的,只要屬性的屬性還有屬性,就可以這么做。

這樣,一個完整的MVVM框架和數(shù)據(jù)綁定就完成了。好了,今天就寫這么多, 一不小心又是凌晨1點半了。最后,歡迎喜歡uwp開發(fā)的同學(xué)加群學(xué)習(xí)交流:193148992。 最后曬一下這個綁定頁面的效果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容