上次已經創建了可運行的基本框架,這篇就說說怎麼把咱們自定義的View自動加載並添加到AvalonDock裏面,AvalonDock裏有3種類型的UI部件,Document, DockableContent以及Floting類型,我主要說一下Document,DockableContent的添加,在AvalonDock裏Document類型可參考VS,DockableContent至關於VS裏的工具欄等,以後我直接在.cs文件裏寫註釋以及解析。html
如今的項目結構:app
運行結果:框架
能夠看到裏面多了一個測試的Document,該Document是由MEF自動加載而且綁定到AvalonDock裏,這裏我只寫一個一個Document,有興趣的能夠本身動手試一試,目前的Document是寫在主程序裏面,其實這Document應該寫在一個單獨的DLL裏面,這就是咱們所謂的插件。 [BY Zengg]ide
DockScreenManager類 工具
1 namespace UICoreFramework 2 { 3 /*DemoApplication裏面的DockViewModel實現該接口,爲了使所有的Documents以及DockableContents集中管理 */ 4 public interface IDockScreenManager 5 { 6 //用與綁定到AvalonDock的Document類型的數據源 7 ObservableCollection<IDocument> Documents { get; } 8 //用與綁定到AvalonDock的Document類型的數據源 9 ObservableCollection<IDockableContent> DockableContents { get; } 10 } 11 public class DockScreenManager : ViewAware, IDockScreenManager 12 { 13 /// <summary> 14 /// ImportMany是MEF的知識,他的做用是把全部實現某個接口,並標記爲Export的類所有倒入, 15 /// 至關於幫咱們自動實例化並添加到List集合裏 16 /// 17 /// </summary> 18 [ImportMany] 19 public ObservableCollection<IDocument> Documents { get; set; } 20 [ImportMany] 21 public ObservableCollection<IDockableContent> DockableContents { get; set; } 22 public DockScreenManager() 23 { 24 25 } 26 } 27 }
DocumentBase類測試
1 /// <summary> 2 /// Document的抽象類,一些抽象操做能夠在裏面寫,爲了方便我就沒寫東西 3 /// DemoApplication的DocTestViewModel就是繼承與該抽象類 4 /// </summary> 5 public abstract class DocumentBase : IDocument 6 { 7 8 9 public DockType Type 10 { 11 get 12 { 13 throw new NotImplementedException(); 14 } 15 set 16 { 17 throw new NotImplementedException(); 18 } 19 } 20 21 public DockSide Side 22 { 23 get 24 { 25 throw new NotImplementedException(); 26 } 27 set 28 { 29 throw new NotImplementedException(); 30 } 31 } 32 33 34 public string DisplayName 35 { 36 get 37 { 38 return "測試界面"; 39 } 40 set 41 { 42 throw new NotImplementedException(); 43 } 44 } 45 46 public bool IsNotifying 47 { 48 get 49 { 50 throw new NotImplementedException(); 51 } 52 set 53 { 54 throw new NotImplementedException(); 55 } 56 } 57 58 public void NotifyOfPropertyChange(string propertyName) 59 { 60 throw new NotImplementedException(); 61 } 62 63 public void Refresh() 64 { 65 throw new NotImplementedException(); 66 } 67 68 public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 69 }
IDockScreen接口this
1 namespace UICoreFramework 2 { 3 /// <summary> 4 /// 只有DockableContent類型有位置的說法 5 /// </summary> 6 public enum DockSide 7 { 8 Left, 9 Top, 10 Right, 11 Bottom 12 } 13 /// <summary> 14 /// Dock的類型 15 /// </summary> 16 public enum DockType 17 { 18 Document, 19 DockableContent, 20 } 21 /// <summary> 22 /// 抽象出基本的Content類型,並實現屬性通知接口,由於之後綁定到AvalonDock是有雙向綁定的,這樣咱們要操做AvalonDock時 23 /// 就能夠直接操做實現該接口的屬性,好比DisplayName的屬性用於綁定到AvalonDock的LayoutItem的Title 24 /// </summary> 25 public interface IDockScreen:INotifyPropertyChangedEx 26 { 27 DockType Type { get; set; } 28 DockSide Side { get; set; } 29 string DisplayName { get; set; } 30 } 31 }
IDocument接口spa
1 /// <summary> 2 /// 抽象出Document接口,暫時不寫實際東西 3 /// </summary> 4 public interface IDocument : IDockScreen 5 { 6 7 }
PanesStyleSelector類插件
1 /// <summary> 2 /// 這個很重要,這是爲使AvalonDock能區別Document和DockableContent類型並返回不一樣的style,兩個類型不一樣style有不一樣的綁定屬性 3 /// 因此要區分開來 4 /// </summary> 5 public class PanesStyleSelector : StyleSelector 6 { 7 public Style ToolStyle 8 { 9 get; 10 set; 11 } 12 13 public Style DocumentStyle 14 { 15 get; 16 set; 17 } 18 /// <summary> 19 /// 區別邏輯在這裏寫 20 /// </summary> 21 /// <param name="item">實現了IDocument或IDockableContent接口的實例</param> 22 /// <param name="container"></param> 23 /// <returns></returns> 24 public override Style SelectStyle(object item, DependencyObject container) 25 { 26 IDockScreen obj = (IDockScreen)item; 27 28 if (item != null) 29 { 30 //斷定爲何類型 31 if (item is IDocument) 32 { 33 return DocumentStyle; 34 } 35 else 36 { 37 return ToolStyle; 38 } 39 } 40 41 return base.SelectStyle(item, container); 42 } 43 }
較第一張更改部分:雙向綁定
DockViewModel類
1 namespace DemoApplication.Views 2 { 3 /// <summary> 4 /// 字符串"DockViewModel"是爲了標記惟一性,在ShellViewModel裏導入時也要指定爲"DockViewModel",這至關於一個key 5 /// </summary> 6 [Export("DockViewModel", typeof(IDockScreenManager))] 7 public class DockViewModel : DockScreenManager 8 { 9 public DockViewModel() 10 : base() 11 { 12 13 } 14 } 15 }
ShellViewModel類
1 namespace DemoApplication 2 { 3 [Export(typeof(IShell))] 4 class ShellViewModel : IShell 5 { 6 readonly IWindowManager windowManager; 7 [ImportingConstructor] 8 public ShellViewModel(IWindowManager windowManager) 9 { 10 this.windowManager = windowManager; 11 12 } 13 /// <summary> 14 /// DockView 15 /// </summary> 16 [Import("DockViewModel")] 17 public IDockScreenManager DockContent { get; set; } 18 } 19 }
MefBootstrapper類
1 protected override void Configure() 2 { 3 /*CompositionContainer 對象在應用程序中有兩種的主要用途。首先,它跟蹤哪些部分可用於組合、它們的依賴項,而且充當任何指定組合的上下文。其次,它提供了應用程序能夠啓動組合的方法、獲取組合部件的實例,或填充可組合部件的依存關係。 4 部件可直接用於容器,或經過 Catalog 屬性來用於容器。在此 ComposablePartCatalog 中可發現的全部部件均可以供容器來知足導入,還包括直接添加的任何部件。*/ 5 //container = new CompositionContainer( 6 // new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x))) 7 // ); 8 9 10 var catalog = new AggregateCatalog( 11 AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>() 12 ); 13 14 container = new CompositionContainer(catalog); 15 16 var batch = new CompositionBatch(); 17 var dockScreenManage = new DockScreenManager(); 18 batch.AddExportedValue<IWindowManager>(new WindowManager());//將指定的導出加入至 CompositionBatch 物件 19 batch.AddExportedValue<IEventAggregator>(new EventAggregator()); 20 batch.AddExportedValue<IDockScreenManager>(dockScreenManage); 21 batch.AddExportedValue(container); 22 batch.AddExportedValue(catalog); 23 container.Compose(batch);//在容器上執行組合,包括指定的 CompositionBatch 中的更改 24 25 container.ComposeParts(container.GetExportedValue<IDockScreenManager>());//因爲DockScreenManager裏有標記爲Import的字段,因此要在MEF容器裏組裝把指定的部件導入 26 }
AvalonDock還支持其餘幾種皮膚,能夠知足大衆的需求:
AeroTheme
ExpressionLightTheme
ExpressionDarkTheme
VS2010Theme
DockableContent類型的實現和Document實現是同樣的,只是實現的接口不一樣,DockableContent實現的是IDockableContent接口,具體請參考Document實現,有疑問的能夠提出來,儘可能幫助解決,解釋寫得略簡單很差意思,可是有源碼參考,若是源碼對你們有幫助的話,求個推薦,回覆或粉的神馬的都好。。。
源碼地址:
http://pan.baidu.com/share/link?shareid=819683340&uk=554439928
若是您看了本篇博客,以爲對您有所收穫,請點擊右下角的 [推薦]
若是您想轉載本博客,請註明出處
若是您對本文有意見或者建議,歡迎留言
感謝您的閱讀,請關注個人後續博客
做者:Zengg 出處:http://www.cnblogs.com/01codeworld/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。