AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(二)
上次已经建立了可运行的基本框架,这篇就说说怎么把我们自定义的View自动加载并添加到AvalonDock里面,AvalonDock里有3种类型的UI部件,Document, DockableContent以及Floting类型,我主要说一下Document,DockableContent的添加,在AvalonDock里Document类型可参考VS,DockableContent相当于VS里的工具栏等,之后我直接在.cs文件里写注释以及解析。
现在的项目结构:

运行结果:

可以看到里面多了一个测试的Document,该Document是由MEF自动加载并且绑定到AvalonDock里,这里我只写一个一个Document,有兴趣的可以自己动手试一试,目前的Document是写在主程序里面,其实这Document应该写在一个单独的DLL里面,这就是我们所谓的插件。 [BY Zengg]
DockScreenManager类
namespace UICoreFramework
{
/*DemoApplication里面的DockViewModel实现该接口,为了使全部的Documents以及DockableContents集中管理 */
public interface IDockScreenManager
{
//用与绑定到AvalonDock的Document类型的数据源
ObservableCollection<IDocument> Documents { get; }
//用与绑定到AvalonDock的Document类型的数据源
ObservableCollection<IDockableContent> DockableContents { get; }
}
public class DockScreenManager : ViewAware, IDockScreenManager
{
/// <summary>
/// ImportMany是MEF的知识,他的作用是把所有实现某个接口,并标记为Export的类全部倒入,
/// 相当于帮我们自动实例化并添加到List集合里
///
/// </summary>
[ImportMany]
public ObservableCollection<IDocument> Documents { get; set; }
[ImportMany]
public ObservableCollection<IDockableContent> DockableContents { get; set; }
public DockScreenManager()
{ }
}
}
DockScreenManager
DocumentBase类
/// <summary>
/// Document的抽象类,一些抽象操作可以在里面写,为了方便我就没写东西
/// DemoApplication的DocTestViewModel就是继承与该抽象类
/// </summary>
public abstract class DocumentBase : IDocument
{ public DockType Type
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
} public DockSide Side
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
} public string DisplayName
{
get
{
return "测试界面";
}
set
{
throw new NotImplementedException();
}
} public bool IsNotifying
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
} public void NotifyOfPropertyChange(string propertyName)
{
throw new NotImplementedException();
} public void Refresh()
{
throw new NotImplementedException();
} public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
}
DocumentBase
IDockScreen接口
namespace UICoreFramework
{
/// <summary>
/// 只有DockableContent类型有位置的说法
/// </summary>
public enum DockSide
{
Left,
Top,
Right,
Bottom
}
/// <summary>
/// Dock的类型
/// </summary>
public enum DockType
{
Document,
DockableContent,
}
/// <summary>
/// 抽象出基本的Content类型,并实现属性通知接口,因为以后绑定到AvalonDock是有双向绑定的,这样我们要操作AvalonDock时
/// 就可以直接操作实现该接口的属性,比如DisplayName的属性用于绑定到AvalonDock的LayoutItem的Title
/// </summary>
public interface IDockScreen:INotifyPropertyChangedEx
{
DockType Type { get; set; }
DockSide Side { get; set; }
string DisplayName { get; set; }
}
}
IDockScreen
IDocument接口
/// <summary>
/// 抽象出Document接口,暂时不写实际东西
/// </summary>
public interface IDocument : IDockScreen
{ }
IDocument
PanesStyleSelector类
/// <summary>
/// 这个很重要,这是为使AvalonDock能区别Document和DockableContent类型并返回不同的style,两个类型不同style有不同的绑定属性
/// 所以要区分开来
/// </summary>
public class PanesStyleSelector : StyleSelector
{
public Style ToolStyle
{
get;
set;
} public Style DocumentStyle
{
get;
set;
}
/// <summary>
/// 区别逻辑在这里写
/// </summary>
/// <param name="item">实现了IDocument或IDockableContent接口的实例</param>
/// <param name="container"></param>
/// <returns></returns>
public override Style SelectStyle(object item, DependencyObject container)
{
IDockScreen obj = (IDockScreen)item; if (item != null)
{
//判定为什么类型
if (item is IDocument)
{
return DocumentStyle;
}
else
{
return ToolStyle;
}
} return base.SelectStyle(item, container);
}
}
较第一张更改部分:
DockViewModel类
namespace DemoApplication.Views
{
/// <summary>
/// 字符串"DockViewModel"是为了标记唯一性,在ShellViewModel里导入时也要指定为"DockViewModel",这相当于一个key
/// </summary>
[Export("DockViewModel", typeof(IDockScreenManager))]
public class DockViewModel : DockScreenManager
{
public DockViewModel()
: base()
{ }
}
}
ShellViewModel类
namespace DemoApplication
{
[Export(typeof(IShell))]
class ShellViewModel : IShell
{
readonly IWindowManager windowManager;
[ImportingConstructor]
public ShellViewModel(IWindowManager windowManager)
{
this.windowManager = windowManager; }
/// <summary>
/// DockView
/// </summary>
[Import("DockViewModel")]
public IDockScreenManager DockContent { get; set; }
}
}
MefBootstrapper类
protected override void Configure()
{
/*CompositionContainer 对象在应用程序中有两种的主要用途。首先,它跟踪哪些部分可用于组合、它们的依赖项,并且充当任何指定组合的上下文。其次,它提供了应用程序可以启动组合的方法、获取组合部件的实例,或填充可组合部件的依存关系。
部件可直接用于容器,或通过 Catalog 属性来用于容器。在此 ComposablePartCatalog 中可发现的所有部件都可以供容器来满足导入,还包括直接添加的任何部件。*/
//container = new CompositionContainer(
// new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)))
// ); var catalog = new AggregateCatalog(
AssemblySource.Instance.Select(x => new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()
); container = new CompositionContainer(catalog); var batch = new CompositionBatch();
var dockScreenManage = new DockScreenManager();
batch.AddExportedValue<IWindowManager>(new WindowManager());//將指定的导出加入至 CompositionBatch 物件
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue<IDockScreenManager>(dockScreenManage);
batch.AddExportedValue(container);
batch.AddExportedValue(catalog);
container.Compose(batch);//在容器上执行组合,包括指定的 CompositionBatch 中的更改 container.ComposeParts(container.GetExportedValue<IDockScreenManager>());//由于DockScreenManager里有标记为Import的字段,所以要在MEF容器里组装把指定的部件导入
}
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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(二)的更多相关文章
- AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(一)
随着IOS7由之前UI的拟物化设计变为如今的扁平化设计,也许扁平化的时代要来了,当然我们是不是该吐槽一下,苹果什么时候也开始跟风了,自GOOGLE和微软界面扁平化过后,苹果也加入了这一队伍. Aval ...
- AvalonDock 2.0+Caliburn.Micro+MahApps.Metro实现Metro风格插件式系统(菜单篇)
这章主要说插件的菜单,可以说菜单是最核心的部分,前面我们已经实现了Document添加,现在主要就是生成具有层级关系的菜单,以及把菜单跟我们自定义的Document关联起来,也就是MenuPart-& ...
- Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)
Caliburn.Micro 杰的入门教程1(翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)Caliburn.Micro 杰的入门教程3, ...
- 从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器
从0到1:使用Caliburn.Micro(WPF和MVVM)开发简单的计算器 之前时间一直在使用Caliburn.Micro这种应用了MVVM模式的WPF框架做开发,是时候总结一下了. Calibu ...
- WPF +MVVM(Caliburn.Micro)项目框架
最近做了一个软件,这个软件不是网站,但是与HTML,AJAX等技术密切相关,也不是只有单纯的数据库增删改查,还涉及到线程协调,比较复杂的文本处理…… 这样的软件,用OA,ERP的框架显然是不合适的,因 ...
- Caliburn.Micro学习笔记(一)----引导类和命名匹配规则
Caliburn.Micro学习笔记目录 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详 ...
- Caliburn.Micro学习笔记(二)----Actions
Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...
- Xamarin 的 MVVM 之 Caliburn.Micro
约定 Caliburn.Micro 以下简称 CMXamarin.Form 以下简称 XF 摘要CM 当前已释出 3.0 beta 版https://github.com/Caliburn-Micro ...
- 开源框架Caliburn.Micro
Caliburn.Micro学习笔记----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeple ...
随机推荐
- JavaScript作用域(链)学习笔记
作用域是javascript老生常谈的问题,在面试题中也经常出现.此文记录本人对js作用域的理解.从以下三个方面深入探讨js作用域和js作用域链. 1.什么是作用域? 2.什么是作用域链? 3.常见面 ...
- Hive通过查询语句向表中插入数据注意事项
最近在学习使用Hive(版本0.13.1)的过程中,发现了一些坑,它们或许是Hive提倡的比关系数据库更加自由的体现(同时引来一些问题),或许是一些bug.总而言之,这些都需要使用Hive的开发人员额 ...
- wamp图标黄色的另一种可能原因
学习php用的是wamp即windows+apache+mysql+php,但是当启动的时候,图标为黄色(正常应为绿色),开始以为是端口的问题,但是将端口改掉依旧如此,后来发现是机器装的sqlserv ...
- Lua数据结构的学习笔记
更多详细内容请查看:http://www.111cn.net/sys/linux/59911.htm table是Lua中唯一的数据结构,其他语言所提供的其他数据结构比如:arrays.records ...
- File.Create创建文件后,需要释放资源
if (!File.Exists(SavePath)) { File.Create(SavePath).Close(); }
- Cocos2d-JS中JavaScript继承
JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来 ...
- (转)Yale CAS + .net Client 实现 SSO(5)
第一部分:安装配置 Tomcat 第二部分:安装配置 CAS 第三部分:实现 ASP.NET WebForm Client 第四部分:实现基于数据库的身份验证 第五部分:扩展基于数据库的身份验证 1. ...
- Java Web动态配置log4j
导入log4j的jar包, 在web.xml中做如下配置 <!-- Log4j Configuration --> <context-param> <param-name ...
- sql server 中更改默认实例
因为安装了多个版本的sql server,会造成同时存在多个实例的情况. 1.关闭旧版本的sql server实例,并设置为手动启动 2.按下图步骤操作,把tcp端口设置为1433 3.重启sql s ...
- JAVA多线程学习--生产者消费者问题
一.问题描述 生产者消费者问题是一个典型的线程同步问题.生产者生产商品放到容器中,容器有一定的容量(只能顺序放,先放后拿),消费者消费商品,当容器满了后,生产者等待,当容器为空时,消费者等待.当生产者 ...