從PRISM開始學WPF(一)WPF?
從PRISM開始學WPF(二)Prism?
從PRISM開始學WPF(三)Prism-Region?
從PRISM開始學WPF(四)Prism-Module?
從PRISM開始學WPF(五)MVVM(一)ViewModel?
從PRISM開始學WPF(六)MVVM(二)Command?
從PRISM開始學WPF(七)MVVM(三)事件聚合器EventAggregator?
0x5 MVVM
蛤蛤,終于到MVVM了。愛掏網 - it200.com特別是前面的Module,忒難寫,反正大概知道是怎么用就好了,具體怎么個容器,怎么個依賴注入,我也不是很懂,Prism重度依賴容器,哪哪都是,哪哪都是依賴容器注入。愛掏網 - it200.com
到目前為止,已經知道怎么去設置Region,怎么去關聯View,和關聯其他Module里的View了。愛掏網 - it200.com那么接下來就是MVVM啦,,°:.( ̄▽ ̄)/$:.° 。愛掏網 - it200.com
先看Wiki怎么對MVVM定義的:
MVVM(Model–view–viewmodel)是一種軟件架構模式。愛掏網 - it200.com
MVVM有助于將圖形用戶界面的開發與業務邏輯或后端邏輯(數據模型)的開發分離開來,這是通過置標語言或GUI代碼實現的。愛掏網 - it200.comMVVM的視圖模型是一個值轉換器,[1] 這意味著視圖模型負責從模型中暴露(轉換)數據對象,以便輕松管理和呈現對象。愛掏網 - it200.com在這方面,視圖模型比視圖做得更多,并且處理大部分視圖的顯示邏輯。愛掏網 - it200.com[1] 視圖模型可以實現中介者模式,組織對視圖所支持的用例集的后端邏輯的訪問。愛掏網 - it200.com
Dior不Dior?首先他不是WPF專有的,現在很多前端框架都實現了MVVM模式,像Vue,Angular。愛掏網 - it200.com那MVVM這么火,他到底有什么神奇的地方呢?數據雙向綁定!數據雙向綁定!數據雙向綁定!
我最早在找MVVM框架的時候,其實并不在乎什么解耦,前后端分離,可測試啥的,我只是受夠了WinForms前臺代碼中 ShowDetails和SetModel,后來發現MVVM可以實現雙向綁定,數據驅動界面顯示,就著了迷(′艸`)。愛掏網 - it200.com扯遠了,我們來看Prism,怎樣實現MVVM的。愛掏網 - it200.com
ViewModel及定位
什么是ViewModel,ViewModel在MVVM中充當了什么角色?
ViewModel是對應的View(數據和行為)的抽象,View只是ViewModel的一個消費者,那么還有其他的消費者嗎?當然有了,那就是單元測試(Unit Test),這個后面說。愛掏網 - it200.comViewModel為View提供數據上下文(DataContext),簡單的說,你View需要展示的東西,都在我這里,你需要跟我綁定,包括數據和命令,不然你就是個靜態的。愛掏網 - it200.com
那怎么為View指定ViewModel呢,通常情況下,我們是為控件指定Datacontext,而Prism為我們提供了更簡單方式,約定。愛掏網 - it200.com
約定的綁定方式
-
Step1 新建一個Wpf項目,新建兩個文件夾Views 和 ViewModels,用來存放View和ViewModel,刪掉MainWindow.xaml,并在Views新建一個新 MainWindow窗體當我們的Shell。愛掏網 - it200.com刪掉App.xaml里的
StartupUri
,新建Bootstrapper.cs
,這是一個最普通的Bootstrapper:
using Microsoft.Practices.Unity;
using Prism.Unity;
using ViewModelLocator.Views;
using System.Windows;
namespace ViewModelLocator
{
class Bootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
{
return Container.Resolve();
}
protected override void InitializeShell()
{
Application.Current.MainWindow.Show();
}
}
}
- Step2 在ViewModels文件夾內新建,一個MainViewModel的類,繼承BindableBase,注意,這里是個類(Class)
MainWindowViewModel.cs
using Prism.Mvvm;
namespace ViewModelLocator.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private string _title = "Prism Unity Application";
public string Title
{
get { return _title; }
set { SetProperty(ref _title, value); }
}
public MainWindowViewModel()
{
}
}
}
-
Step3 修改
MainWindow.xaml
,覆蓋下面的代碼:(當前也可以不覆蓋,對比發現,我們這里只多了一點東西)
Tips:數據綁定Title="{Binding Title}" ,Title是對應ViewModel里的一個公開屬性。愛掏網 - it200.com
運行后發現,窗口的Title正式MainWindowViewModel里Title的值,可是我們并沒有為MainWindow指定ViewModel啊,正常的綁定看上去是應該是這樣
或者這樣
蛤蛤,剛開始我也很懵逼,可是我愛學習,在Prism的源碼Prism.Mvvm.ViewModelLocationProvider
中我發現了這個:
///
/// ViewModelfactory that provides the View instance and ViewModel type as parameters.
///
static Func
是不是豁然開朗?
最終,你的程序目錄是這樣的:
我們不一樣,定制約定
約定就是要來被打破的,有人可能覺得后綴加一個ViewModel實在是LowB,我想改變他,可以不可以?當然闊以啦。愛掏網 - it200.com
貼心的Bootstrapper為我們提供了一個可重寫的ConfigureViewModelLocator的方法來配置ViewModel的定位器,如果你想修改默認的約定為View的名字后面+VM,你可以在Bootstrapper.cs
這樣寫:
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
{
var viewName = viewType.FullName;
var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
var viewModelName = $"{viewName}VM, {viewAssemblyName}";
return Type.GetType(viewModelName);
});
}
我就是我,是顏色不一樣的煙火
這世界上不乏個性鮮明的人,你們那些約定和打破的約定還不都是一路貨色。愛掏網 - it200.com我就要不一樣的,我想跟誰綁在一起就跟誰綁在一起。愛掏網 - it200.com好,你跟誰好是你的自由,Prism不能限制你,不然你會投訴它不民主。愛掏網 - it200.com
如果你想指定你綁定的ViewModel對象又不想遵循一定的規則,你同樣可以在ConfigureViewModelLocator方法中注冊綁定,像下面這樣:
protected override void ConfigureViewModelLocator()
{
base.ConfigureViewModelLocator();
// type / type
//ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), typeof(CustomViewModel));
// type / factory
//ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), () => Container.Resolve());
// generic factory
//ViewModelLocationProvider.Register(() => Container.Resolve());
// generic type
ViewModelLocationProvider.Register();
}
當然了,在xaml中的
prism:ViewModelLocator.AutoWireViewModel="True"
依舊是必不可少的。愛掏網 - it200.com