——我的《簡影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。 最后曬一下這個綁定頁面的效果。
