用了幾天時間看了一下開源框架Caliburn.Micro
這是他源碼的地址http://caliburnmicro.codeplex.com/
文檔也寫的很詳細,自己在看它的文檔和代碼時寫了一些demo和筆記,還有它實現的原理記錄一下
學習Caliburn.Micro要有MEF和MVVM的基礎
先說一下他的命名規則和引導類
以后我會把Caliburn.Micro的
Actions
IResult,IHandle
IConductor ,Conductor<T>
這些常用功能寫下來。
先看一下Caliburn.Micro的大概流程,畫的不太好,先這樣吧
好了,我們開始今天的筆記。
從一個小例子說起 Demo下載:BootstrapperAndConventions.rar
這個例子是有父窗體打開一下子窗體的小功能
程序要引入的三個類庫
Caliburn.Micro
System.Windows.Interactivity
和
System.ComponentModel.Composition
上邊兩個Caliburn.Micro的例子里有提供下邊的在Vs里就能找到
看一下引導類
public interface IShell { } public class MyBootstrapper:Bootstrapper<IShell> { private CompositionContainer _container; //用MEF組合部件 protected override void Configure() { _container = new CompositionContainer( new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>())); ///如果還有自己的部件都加在這個地方 CompositionBatch _batch = new CompositionBatch(); _batch.AddExportedValue<IWindowManager>(new WindowManager()); _batch.AddExportedValue<IEventAggregator>(new EventAggregator()); _batch.AddExportedValue(_container); _container.Compose(_batch); } //根據傳過來的key或名稱得到實例 protected override object GetInstance(Type service, string key) { string _contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key; var _exports = _container.GetExportedValues<object>(_contract); if (_exports.Any()) { return _exports.First(); } throw new Exception(string.Format("找不到{0}實例", _contract)); } //獲取某一特定類型的所有實例 protected override IEnumerable<object> GetAllInstances(Type service) { return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(service)); } //將實例傳遞給 Ioc 容器,使依賴關系注入 protected override void BuildUp(object instance) { _container.SatisfyImportsOnce(instance); } }
我們要實現Bootstrapper<T>這個類
一般我用我MEF做為容器,重寫這個類的三個方法,寫法也比較固定,就像上邊我寫的那這樣
如果有自己的一些東西需要配置可以寫在Config里
除了上邊的三個方法還有OnStartup和OnExit分別是程序進入和退出的執行事件,可根據自己的需要做相應的重寫
還要在App.xaml里加入
<Application x:Class="CalibrunMicAction.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:booter="clr-namespace:CalibrunMicAction"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary> <booter:Mybootstrapper x:Key="appbooter"/> </ResourceDictionary> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
這樣程序 就會打開Export IShell的窗體
原理
是根據反射有MEF 去查找容器里是否有Exprort IShell的ViewModel如果有就根據名稱去匹配相應的View映射關系並打開,
如果沒有找到就拋出異常
<Window x:Class="WpfApplication1.MyMainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MyMainView" Height="300" Width="300"> <StackPanel> <TextBlock x:Name="StrMain" FontSize="50"/> <Button x:Name="OpenOneChild" Content="OpenAWindow" Width="120" Height="30"/> </StackPanel> </Window>
MainViewModel
using Caliburn.Micro; using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using System.Text; namespace WpfApplication1 { [Export(typeof(IShell))] public class MyMainViewModel { readonly IWindowManager _myWM; public string StrMain { get; private set; } [ImportingConstructor] public MyMainViewModel(IWindowManager wm) { StrMain = "Main!!!!!!"; _myWM = wm; } MyChildOneViewModel _MyChildW = new MyChildOneViewModel(); public void OpenOneChild() { _myWM.ShowDialog(_MyChildW); } } }
你會發現MainView的后台代碼和前台都沒有指定ViewModel
這是Caliburn.Microj里很棒的一點命名匹配規則,原理:它用利用反射和正則表達式去匹配View和ViewModel
系統現有的是自動匹配名稱為View和ViewModel 、PageView和PageViewModel結尾的窗體和類
如果想自己定義一種匹配規則也是可以的,我這就就不講了
運行起來你會發現
TextBlock和Button的屬性和事件也自動匹配上了
原理:
匹配好View和ViewModel后
去查找View里的元素名稱和viewModel里的方法或屬性是否有一至的如果有一至的就綁定
!注意!:給控件命名的時候如txt_abc這樣加下划線Calibrn會把這個名字分開
成txt和abc兩個屬性它會去txt屬性里去找abc屬性綁定
代碼里打開子窗體是用的Caliburn.Micro自己的IWindowManager接口
這是一個專門用來打開窗體的類
它可以以Show() ShowDialog還有ShowPopup形式打開窗體
今天就先說到這,下次會寫一下Caliburn的Actions
Demo下載:BootstrapperAndConventions.rar