iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
Mobile Development

Re: 從零開始用 Xamarin 技術來復刻過去開發的一個 App : TopStore系列 第 5

EP 5: Use self-define Code Snippet to improve Coding Experience for NotifyProperty in ViewModel

  • 分享至 

  • xImage
  •  

Hello, 各位 iT邦幫忙 的粉絲們大家好~~~

本篇是 Re: 從零開始用 Xamarin 技術來複刻過去開發的一個 App: TopStore 系列文的 EP5。

當我們在 EP2 的介紹時調整了 Xamarin.Forms 專案當中的結構,說是為了要搭配 MVVM 框架,來讓我們的專案符合 MVVM 的這種開發框架的運用,但到目前為止似乎都沒有談到這部分的運用,本 EP5 就要來談談有關於這部分的處理囉~~~

那我們就開始吧! Go~~~


在 Xamarin.Forms 的專案當中,我們除了針對專案結構調整以利在使用 MVVM 的框架過程當中容易識別外,最主要我們還是要利用 Xamarin.Forms 配合 MVVM 框架所設計的 "Binding Engine" 所使用的 Binding (繫結)技術,讓 View 跟 ViewModel 能去做一個繫結的處理。

而這個繫結的處理,我們會需要用到 .NET 所設計的一個位在 System.ComponentModel 命名空間下公開介面(public Interface) "INotifyPropertyChanged"。

在這個 INotifyPropertyChanged 的 Interface 的使用時,就必須要去處理一些 Interface 的實作,其實不是只有在 Xamarin.Forms 技術才這樣子用,在 .NET 的 WPF 的技術,或者是一些 .NET 其他的 Client 端的應用技術 (UWP),也會透過這樣的方式,讓應用程式的 View 跟 ViewModel 之間的一個互動能更加地便利。

在這個部分上的話,如果按照原本 INotifyPropertyChanged 的官方文件 慢慢去處理 "INotifyPropertyChanged" 的實作,當然會比較辛苦一點。

而我已經有一個實作好 "INotifyPropertyChanged" 介面的 Library,並且也發佈成一個 Nuget 的套件,可供大家直接安裝下載使用。

所以在這個 EP5 的介紹裡面,就直接帶大家去使用這個已經實作好這個 INotifyPropertyChanged 的 Nuget 套件,就可以比較快速的去完成這個 Binding (繫結)與 MVVM 框架撰寫的前置動作。

順帶一提,類似這樣子的一個前置動作,其實網路上有透過 "AOP" (Aspect Oriented Programming)技術的方式來完成實作 "INotifyPropertyChanged",比較著名的 Framework 就是 PostSharp MVVM
PostSharp 所設計的 MVVM

對照上圖的 PostSharp 官網 的介紹寫法,就可以知道 PostSharp 可以讓各位為了使用 MVVM 框架要實作 INotifyPropertyChanged 時,透過用 PostSharp 的 Library 只要直接掛上相關的 Attribute 即可完成實作。

如果想要試用該 PostSharp 的話,也可直接下載 PostSharp 的延伸模組 在 Visual Studio 中來安裝試用看看喔!

若透過我放在 Nuget 的套件來實作 INotifyPropertyChanged 的話,雖然已經是簡化了實作 INotifyPropertyChanged 許多事情,但是在後續的一些處理上仍然會比較辛苦些,還是有很多地方比不上人家已經做好的整個透過 AOP 來處理的 Framework,還是需要得自己去刻一些東西,這會比較辛苦的部分。

在刻一些東西的時候呢,我們也可以透過 Visual Studio 帶給我們的一些小技巧,設計所需的 code snippet 來去完成這些瑣碎的事情,除了來加速自己的開發外,還是可以了解到原本設計 "INotifyPropertyChanged" 時的內涵喔~~~

首先,在我們的這個 Xamarin.Forms 的專案裡面,我們就來安裝一下這個協助實作 INotifyPropertyChanged 的 Nuget 套件
Xam.Plugin.BaseBindingLibrary 在 Nuget 網站

找到專案管理 Nuget 套件這個部分,再點到 "瀏覽" 的分頁後直接在搜尋框裡面搜尋 "Xam.Plugin.BaseBindingLibrary" 這個 Nuget 套件
Xam.Plugin.BaseBindingLibrary 在 Visual Studio 的 Nuget 套件中搜尋

安裝在這個 Xamarin.Forms 的專案裡面就可以,不需要安裝到其他的專案。另外,Visual Studio 安裝 Nuget 套件期間會有授權 (MIT) 與變更同意的一個請求動作,當這樣子安裝完成的時候會看到在相依性的套件裡面出現它。
Xam.Plugin.BaseBindingLibrary 在 Visual Studio 的 Nuget 套件中搜尋

接下來在 Xamarin.Forms 的專案中所設計 ViewModes 資料夾的部分,我們就可以開始設計與 Page 所對應的 ViewModel 類別,理論上我們就要實作就這四個 Page 對應的 ViewModel,但又因為在要實做這個 ViewModel 的過程,可能都會有一些共通的設計出現。

所以通常在這邊的選擇,就是先做一個基底 ViewModel 類別,在這邊就把它命名的部分叫做 BasePageViewModel。會這樣取就是說後面會有一個 ViewModel 的名稱,就會是讓自己知道說這個類別,是用來作為 ViewModel 的使用用途。
BasePageViewModel 的撰寫 1

這只是一個個人的命名習慣,各位可以自己根據需要做一些調整,或著是開發團隊可以去討論跟制定相關的開發慣例。

這邊我們就直接在 public class BasePageViewModel 後面直接撰寫繼承 BaseBindingLibrary 當中的 "BaseNotifyProperty"。
BasePageViewModel 的撰寫 2

透過這個繼承類別的動作就取代了很多在官方文件上要實作 "INotifyPropertyChanged" 這個 Interface 的處理。

就如果我們沒有要做一些很特殊的設計,就可能就可以直接往其他對應 Page 的 ViewModel 去設計了,但因為通常現在我們的 App 應該都對網際網路很依賴,所以每一個要呈現的頁面,都要能隨時地偵測到網際網路存不存在,並且做出對應的畫面的 UI 反應。

而這個 "網際網路是否已連線" 的這個狀態,基本上每個頁面都會用到,所以在這裡這個 BasePageViewModel,就直接先幫它設計這個 Property 在這裡,以便處理 "網際網路是否已連線" 的狀態。

這個部份我有做成 code snippet,所以你會看到我這邊就直接打這個 code snippet 的縮寫 "prop",再按 "Tab" 兩下,那 Visual Studio 就會自動地幫我長出對應那個已經設計的 BaseNotifyProperty 所要對應的 NotifyProperty 的撰寫。

NotifyProperty 的撰寫 1
NotifyProperty 的撰寫 2

另外,那這個設計網際網路有通跟不通兩種狀態,所以就設計成 bool 的型態。
NotifyProperty 的撰寫 3

本來為了要搭配實作 "INotifyPropertyChanged" 這個 Interface 所要完成 NotifyProperty 的撰寫頗為繁瑣,在這邊透過 "prop" 的 "code snippet" 這些小技巧就能將這個 NotifyProperty 這樣子就做完了。

後面的話我們就在新增一個設計,就是要給 PeoplePage 設計對應的 ViewModel。

所以一樣,再繼續於 ViewModels 資料夾中新增設計一個新的類別叫做 "PeoplePageViewModel" 這樣子的一個名稱,這樣的名稱也是為了方便識別對應給 PeoplePage 用的 ViewModel。

PeoplePageViewModel 的撰寫 1
PeoplePageViewModel 的撰寫 2

再來這邊我們就可以直接繼承我們的前面所完成的那個 BasePageViewModel 這樣就完成了。
PeoplePageViewModel 的撰寫 3

我們在這個 PeoplePage 的 ViewModel 裡面,那基本上就會設計兩個東西:
第一個可能會有一個 People 的集合資料要做儲存。
第二個大概就會是相關的一些 Command 去做頁面控制動作的反應。

所以在這邊我們就來完成 People 的這個集合資料的 NotifyProperty 的設計。

People 集合資料 NotifyProperty 的撰寫 1

那這個集合會是使用已經有實作好雙向 Binding 的一個集合叫做 ObservableCollection,它會是在 System.Collections.ObjectModel 命名空間底下,可以先撰寫好它的命名空間的 using。
People 集合資料 NotifyProperty 的撰寫 2

那當然因為它的這個集合裡面的每一個元素,在這邊我要把它設計叫做 Person,那我們就直接把 ObservableCollection 的泛型設計為 Person,而這個 Person 呢為了不影響我們當前程式的撰寫,我們先透過 Visual Studio 的提示來快速產生,等一下再做 Person 的一個放置的調整。
People 集合資料 NotifyProperty 的撰寫 3

那接著再回到我們的這邊這個集合名稱就叫 People,最後按一下那 Enter 離開 code snippet 的編輯。
People 集合資料 NotifyProperty 的撰寫 4

在本 EP 最後再來稍微來整理一下,在前面透過 Visual Studio 自動產生的 Person 的類別,當初它是自動產生的時候,如果沒有做太多調整,理論上它會產生同一個資料夾當中(也就是 ViewModels 這個資料夾)。

所以我們來將它從 ViewModels 資料夾移動到 Models 資料夾中,既然搬移過去了就也幫 Person 應該所在的 namespace 也稍微修正一下,把它改到 TopStoreApp.Models 的命名空間底下。
Person 搬移到 Models 資料夾下與命名空間修正

那隨之而來會遇到的一個問題,當初的 PeoplePageViewModel 這個類別裡面所使用的 Person 類別,它會不知道在哪裡找到該 Person 類別。
PeoplePageViewModel 使用 Person 類別問題處理 1

一樣就是使用 Visaul Studio 提供的命名空間修正,這次則是使用了 using TopStore.Models 這樣的修正。
PeoplePageViewModel 使用 Person 類別問題處理 2

好的,撰寫到這邊我們先整個 Xamarin.Forms 的專案重新建置 (Ctrl + B) ,確認到目前為止所變更的程式碼在編譯上都沒問題,那我們在繼續到下個階段的部分囉。

Xamarin.Forms 專案建置 1

確認沒有問題的話,後續繼續要設計的部分,就留待 EP6 再繼續介紹囉~~~
Xamarin.Forms 專案建置 2

謝謝各位,我們下篇見^_<


上一篇
EP 4: Use Fonts to design Icon in TopStore App
下一篇
EP 6: Use self-define Code Snippet to improve Coding Experience for design Command in ViewModel
系列文
Re: 從零開始用 Xamarin 技術來復刻過去開發的一個 App : TopStore32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言