AvalonDock 2.0+Caliburn.Micro+MahApps.Metro實現Metro風格插件式系統(二)

  上次已經創建了可運行的基本框架,這篇就說說怎麼把咱們自定義的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 }
DockScreenManager

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     }
DocumentBase

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 }
IDockScreen

IDocument接口spa

1 /// <summary>
2     /// 抽象出Document接口,暫時不寫實際東西
3     /// </summary>
4     public interface IDocument : IDockScreen
5     {
6         
7     }
IDocument

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         }
MefBootstrapper

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/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。

相關文章
相關標籤/搜索