1. 程式人生 > >Mvvm Light Toolkit 入門

Mvvm Light Toolkit 入門

term glob threading 修改 face 情況 同時 roc 開發人員

原文:Mvvm Light Toolkit 入門

前言

之前學習UWP的時候就一直看到有關MVVM的資料但是一直沒有系統的去學,最近正好有時間,特地來攻破這個點,順便學習一下VS與GitHub的鏈接和MarkDown的語法。
下面的附件裏有這篇博客裏用到的Demo工程,我已經加上了比較詳細的註釋,可以幫助理解代碼,歡迎點擊查看。

MVVM簡介

MVVM(Model-View-ViewModel)是一種程序模式,是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。它立足於原有MVP框架並且把WPF的新特性糅合進去,以應對客戶日益復雜的需求變化。

技術分享圖片

如圖,View就是視圖,是呈現給用戶的界面,它接受用戶的交互,也為用戶顯示數據;ViewModel是視圖模型,裏面是顯示邏輯,ViewModel與View進行綁定;然後是Model,也就是數據模型,主要用來給ViewModel提供數據,至於業務邏輯應該放在Model裏還是ViewModel裏似乎沒有絕對的正確答案,兩種方式都有人用。

MVVM模式有幾大優點:

  1. 低耦合。視圖(View)可以獨立於Model變化和修改,一個ViewModel可以綁定到不同的”View”上,當View變化的時候Model可以不變,當Model變化的時候View也可以不變。
  2. 可重用性。你可以把一些視圖邏輯放在一個ViewModel裏面,讓很多view重用這段視圖邏輯。
  3. 獨立開發。開發人員可以專註於業務邏輯和數據的開發(ViewModel),設計人員可以專註於頁面設計,使用Expression Blend可以很容易設計界面並生成xml代碼。
  4. 可測試。界面素來是比較難於測試的,而現在測試可以針對ViewModel來寫。

MVVM Light框架簡介

MVVM Light是一種MVVM的實現。它不是唯一的一種實現,但它是現在大家公認的比較好的一個實現。
MVVM Light功能設計的非常靈活,非常註重實現,它實現了MVVM設計模式基礎的框架如ViewModelBase類,實現了泛型Command< T >,這些都是MVVM基礎。
MVVM Light有個創造性的設計就是消息通知(Messenger),這個設計非常的出色,讓View與ViewModel的通信變的非常簡單,實現了低耦合的設計原則。

一般我們說到MVVM Light都是指的MVVM Light Toolkit這個工具包,這個工具包的主要目的是加速 MVVM 應用程序在 Windows Universal、WPF、Silverlight、Xamarin.iOS、Xamarin.Android 和 Xamarin.Forms 的開發與創造。
MVVM Light Toolkit可以幫助我們從模型中分離視圖,創建簡潔和易於維護和擴展的應用程序。它還創建可測試的應用程序,並允許你有多個瘦用戶界面層(這是更難自動測試的)。
該工具包在它創建的應用程序中特別強調“可設計” (即能夠在Blend中打開和編輯用戶界面),包括創建設計時數據,以使Blend使用者能夠在和數據控件一起進行“可視化”的工作。

MVVM Light Toolkit 的安裝

直接安裝插件
打開VS,菜單欄選擇:“工具” / “擴展和更新”,然後進入 “聯機” / “Visual Studio MarketPlace” 選項卡,在搜索框中輸入“mvvm light”,選擇點擊安裝即可。
技術分享圖片
通過這個方法安裝以後,新建工程的時候可以看到預設的幾個模板:
技術分享圖片

如圖,從上到下依次是UWP、安卓、iOS和WPF工程的模板,不過通過模板建立的UWP工程有點臃腫,我覺得算得上是一個Demo,各種特性都基本包括了,WPF工程倒是只有一個TextBlock在裏面,比較簡潔。

在項目中安裝NuGet包
打開項目,在解決方案資源管理器中右擊“引用”項,點擊“管理NuGet程序包”,搜索“mvvm light”,安裝“MVVMLightLibs”即可。
技術分享圖片
這個方法安裝之後新建工程的時候沒有模板

MVVM Light Toolkit 工程目錄及文件

MVVM,自然就有Model、View和ViewModel三個部分了,以框架生成的的UWP模板為例,Model文件夾裏面是數據模型,ViewModel文件夾裏是視圖模型,而視圖則放在了根目錄下面(當然你也可以新建一個View文件夾來存放視圖)。

技術分享圖片

Design文件夾:
裏面存放的是上面簡介中提到的“設計時”數據,在VS Blend裏打開項目時,運行時數據會填充到數據控件中,方便設計界面。
DesignDataService類,類似下面提到的DataService類。
Model文件夾:
IDataService接口裏定義了一個名為GetData()的異步方法;
public interface IDataService
{
    Task<DataItem> GetData();
}

DataService類實現了前面定義的方法,並返回了一個DataItem實例。

public Task<DataItem> GetData()
{
    // Use this to connect to the actual data service(用來連接實際數據服務)
    //
    // Simulate by returning a DataItem
    var item = new DataItem("Welcome to MVVM Light");
    return Task.FromResult(item);
}
DataItem是數據模板。
ViewModel文件夾:
ViewModelLocator類包含了這個應用中所有ViewModel的靜態引用並提供了綁定的進入點。並通過SimpleIoc這個容器實現了依賴註入。

使用ViewModelLocator的好處:

  1. View和ViewModel之間不再直接引用,而是通過ViewModelLocator關聯。
  2. 儲存在ViewModelLocator裏的ViewModel類似與單例的存在,可以在全局引用綁定
  3. 避免了某些情況下頻繁創建ViewModel,卻未做好資源釋放造成的內存泄漏。(並不是說所有ViewModel都必須放到ViewModelLocator裏)

SimpleIoc的使用方法:

  1. 將自己的類註冊到SimpleIoc

    SimpleIoc.Default.Register(()=>new MyClass());
  2. 把MainViewModel也註冊到SimpleIoc

    SimpleIoc.Default.Register<MainViewModel>();
  3. 在Main屬性中通過ServiceLocator.Current.GetInstance()方法獲取實例

    public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
  4. 在MainViewModel的構造函數中匹配MyClass類

    public MainViewModel(MyClass data)
    {
        WelcomeTitle = data.Name;
    }

MainViewModel類則是與MainPage相對應的ViewModel,通過綁定實現MainPage中的各種行為。

App.xaml文件:
將ViewModelLocator作為資源添加到全局的Application.Resources裏。
<Application.Resources>
    <!-- 將ViewModelLocator作為資源添加到全局的Application.Resources裏 -->
    <!--Global View Model Locator-->
    <vm:ViewModelLocator x:Key="Locator"
                         d:IsDataSource="True" />
</Application.Resources>
MainPage.xaml文件:
第11行,以StaticResource的形式獲取ViewModelLocator實例的資源,並Binding到了頁面的DataContext屬性。
...
DataContext="{Binding Main, Source={StaticResource Locator}}">

通過綁定控件的Command(或者Behavior)屬性實現各種點擊後的功能。

<Button Content="Increment counter"
    HorizontalAlignment="Stretch"
    Margin="0,0,0,20"
    FontSize="24"
    Command="{Binding IncrementCommand, Mode=OneWay}"
    Foreground="White" />
SecondPage.xaml文件:
非常簡單,沒有用到MVVM模式,采用默認的Code Behind方式實現顯示和頁面返回。

MVVM Light的程序集和命名空間

GalaSoft.MvvmLight.dll程序集

GalaSoft.MvvmLight 命名空間
最頂層的命名空間,包含了MvvmLight的主體,最核心的功能都在這裏。

  • ICleanup
    實現該接口的ViewModel需要在Cleanup方法中釋放資源,特別是-=event。

  • ObservableObject
    該類實現了INotifyPropertyChanged接口,定義了一個可通知的對象基類,供ViewModelBase繼承。

  • ViewModelBase
    繼承自ObsevableObject,ICleanup。
    將作為MvvmLight框架下使用的ViewModel的基類。
    主要提供Set和RaisePropertyChanged供外部使用。同時會在Cleanup方法裏,Unregister該實例的所有MvvmLight Messager(在GalaSoft.MvvmLight.Messaging命名空間內定義)。

  • RelayCommand
    提供了一個ICommand接口的實現

  • RelayCommand< T >
    提供了ICommand接口的泛型實現

GalaSoft.MvvmLight.Helpers 命名空間
MvvmLight框架內部使用的一些輔助類,框架的使用者不直接接觸該命名空間。

GalaSoft.MvvmLight.Messaging 命名空間
消息類命名空間,提供全局的消息通知。

GalaSoft.MvvmLight.Views 命名空間
和View結合較緊密,ViewModel通過依賴該命名空間下的類,來避免直接引用View,用以解耦代碼對具體的平臺的依賴。

  • IDialogService
    對系統彈框消息的抽象。
    針對具體平臺會在GalaSoft.MvvmLight.Platform程序集裏分別實現

  • INavigationService
    對頁面導航的抽象,不同平臺會有不同實現。

GalaSoft.MvvmLight.Extras程序集

GalaSoft.MvvmLight.Ioc 命名空間
依賴註入使用的容器放在這個命名空間。

  • ISimpleIoc
    IOC(Inverse Of Control)控制反轉,也就是依賴註入(Dependency Injection),簡單可以理解為一個托管的容器,替你創建和管理對象。在MVVM中,一般是ViewModel.

  • PreferredConstructorAttribute
    該類繼承自Attribute,不常用。
    當ViewModel存在一個以上的構造函數時,可以通過他來指定SimpleIoc默認調用的構造函數。

  • SimpleIoc
    ISimpleIoc接口的實現。功能簡單實用。

GalaSoft.MvvmLight.Platform程序集

依賴平臺具體實現的功能會放到這個程序集裏

GalaSoft.MvvmLight.Threading 命名空間

  • DispatcherHelper
    非UI線程操作UI線程時用到的幫助類,已針對各平臺不同的寫法做了封裝。

GalaSoft.MvvmLight.Views 命名空間

  • DialogService
    IDialogService接口的實現。

  • NavigationService
    INavigationService接口的實現。

附件

上面用到的Demo(已詳細註釋)

參考

MvvmLight框架使用入門(一)
MvvmLight框架使用入門(二)
MVVM Light Toolkit

Mvvm Light Toolkit 入門