通过查看DesignSurface的View的代码: IComponent rootComponent = ((IDesignerHost) this._host).RootComponent; ........ IRootDesigner designer = ((IDesignerHost) this._host).GetDesigner(rootComponent) as IRootDesigner; ......... ViewTechnology[] supportedTechnologies = designer.SupportedTechnologies; int index = 0; while (index < supportedTechnologies.Length) { ViewTechnology technology = supportedTechnologies[index]; return designer.GetView(technology); } (ViewTechnology 枚举 ,定义设计器宿主所支持的技术集的标识符。一般我们使用Default, 指定默认的视图技术支持就可以了。关于IComponent 可以参考下面的两篇文档) 1. IComponent rootComponent = ((IDesignerHost) this._host).RootComponent; 我们可以看到,他先通过host(设计宿主)获得根组件,(比如我们设计一个顺序工作流,那么根组件就是一个SequentialActivity,如果设计一个Form,那么根组件就是一个Form) 2. IRootDesigner designer = ((IDesignerHost) this._host).GetDesigner(rootComponent) as IRootDesigner; 这里通过host(设计宿主)的GetDesigner方法,获得了根组件的根设计器(对比前面的例子,也就是一个SequentialWorkflowDesigner或者FormDocumentDesigner) 3.这里我们做个例子,一路追踪SequentialWorkflowDesigner,最后找到了它的基类,ActivityDesigner,实现了IRootDesigner 接口,查看他的GetView代码: object IRootDesigner.GetView(ViewTechnology technology) { DesignSurface service = this.GetService(typeof(DesignSurface)) as DesignSurface; IDesignerHost host = this.GetService(typeof(IDesignerHost)) as IDesignerHost; if (((this.workflowView == null) && (service != null)) && ((host != null) && (host.RootComponent == this.Activity))) { this.workflowView = this.CreateView(technology); } return this.workflowView; } 或者FormDocumentDesigner的父类DocumentDesigner的GetView: object IRootDesigner.GetView(ViewTechnology technology) { if ((technology != ViewTechnology.Default) && (technology != ViewTechnology.WindowsForms)) { throw new ArgumentException(); } return this.frame; } 我们可以发现,他们返回的是WorkflowView的实例或者DesignerFrame的实例,前者继承了UserControl,或者继承了Control,所以他们都能被添加到Panle子类的容器中。 关于Host: 我们可以发现他在DesignSurface构造的时候获得: public DesignSurface() : this((IServiceProvider) null) { } public DesignSurface(IServiceProvider parentProvider) { this._parentProvider = parentProvider; this._serviceContainer = new DesignSurfaceServiceContainer(this._parentProvider); ServiceCreatorCallback callback = new ServiceCreatorCallback(this.OnCreateService); this.ServiceContainer.AddService(typeof(ISelectionService), callback); this.ServiceContainer.AddService( typeof(IExtenderProviderService), callback); this.ServiceContainer.AddService( typeof(IExtenderListService), callback); this.ServiceContainer.AddService( typeof(ITypeDescriptorFilterService), callback); this.ServiceContainer.AddService( typeof(IReferenceService), callback); this.ServiceContainer.AddService(typeof(DesignSurface), this); this._host = new DesignerHost(this); } 其他的战且不管,发现Host直接被new成了DesignerHost,他是IDesignerHost的默认实现。这个我们只能查看代码,也没有相关的文档,太难分析了。通过其他方法: 设计加载器 我们知道我们是可以自定义设计加载器的,通常在这里面我们会自己加一些服务,比如工具条,右键菜单等。代码如下: internal sealed class WorkflowLoader : WorkflowDesignerLoader { #region Overrides from WorkflowDesignerLoader protected override void Initialize() { base.Initialize(); // Add all the services to the loaderhost IDesignerLoaderHost host = LoaderHost; if (host != null) { this.SetBaseComponentClassName("foo.Workflow1"); host.AddService(typeof(IMenuCommandService), new WorkflowMenuCommandService(host)); host.AddService(typeof(IToolboxService), new ToolboxService(host)); } } } 我们前面刚刚说过,我们可以通过给设计面加服务来实现类似的操作,怎么这里有可以呢?而且,使用自定义设计器加载器的代码方式也很让人迷糊: DesignSurface designSurface = new DesignSurface(); WorkflowLoader loader = new WorkflowLoader(); designSurface.BeginLoad(loader); 难道在调用ds的BeginLoad以后,就有某种方式调用了DesignLoader的Initialize?并且,将服务加到了ds中? 查看designSurface.BeginLoad(loader);的代码: internal void BeginLoad(DesignerLoader loader) { this._loader = loader; try { this._loader.BeginLoad(this); } ....... } 我们可以发现关键的代码是他调用了DesignerLoader 的BeginLoad,并且把自己(DesignSurface)给传递进去,通过查看WorkflowDesignerLoader 父类BasicDesignerLoader的BeginLoad: public override void BeginLoad(IDesignerLoaderHost host) { if (this._host == null) { this._host = host; .............. this.Initialize(); host.Activated += new EventHandler(this.OnDesignerActivate); host.Deactivated += new EventHandler(this.OnDesignerDeactivate); } } 哈哈,关键的代码发现了,我们发现BeginLoad的参数正是IDesignerLoaderHost ,并且将传进来的DesignSurface赋给了它的一个实例变量,private IDesignerLoaderHost _host; 并且调用了Initialize()方法。 再回头看我们自定义加载器的Initialize()方法就很清楚了,我们获得了IDesignerLoaderHost (其实就是DesignSurface,并且将服务加给了DesignSurface)。 现在再来看一下IDesignerLoaderHost 的定义:提供一个接口,该接口可扩展设计器宿主以支持从序列化状态加载。 从字面的意思来说,IDesignerLoaderHost 是”设计器加载器的宿主“,搞不明白为什么他是DesignSurface?? 1.我们的设计器宿主(DesignHost)被包含进了设计面(DesignSurace)中。可以通过设计器宿主的GetDesigner(设计的类型(Form/Button))方法获得设计器。 IDesigner designer = ((IDesignerHost) this._host).GetDesigner(rootComponent); 2.获得设计器以后就能通过设计器的GetView返回该设计器的视图显示。(就是我们可以看到的设计的样子) 3.可以通过设计宿主的designerHost.Container.Add(activity, rootSiteName);加入向我们的设计面中加入控件。 4.有时候也需要保存/加载设计器,所以就有了自定义的DesignLoader(设计器加载器) |
|