运行时窗体设计器Runtime FormDesigner之高阶篇
写在前面:之前已经有两篇文章对Form Designer运行了分析和展示,具体展示了几个重要的开源Form设计器,也介绍了最基本的Form设计器的编写方式。而在介绍Hosting设计器时,没有提及到代码的展示与编译运行机制,下面,本文就对运行时Form设计器的代码转换和编译机制进行分析和学习。下面介绍Designerhost工具。
界面效果图
代码的产生
将注意力投放到SampleDesignerLoader.cs类,上图中Design,C# Source,VB Source,XML视图的变化,都会产生事件,事件处理方法就是SampleDesignerLoader类的Flush方法,表示对当前控件与代码的刷新。
一个重要的类,类中的类
System.CodeDom.CodeCompileUnit
在.Net中,一个源文件,如C#写好的.cs文件,其实可以转化为一个类中类CodeCompileUnit,这个类中类有构造函数,方法体,属性,命名空间等等的定义。如引入System命名空间,你可以这样写Imports.Add(new CodeNamespaceImport("System")); CodeConstructor是用来定义构造函数的。可以说,一个类实体的定义,运行时本身就是一个CodeCompileUnit类的实例。类的序列化功能,就是由CodeCompileUnit发起的重要功能。
类的序列化可以将一个类变成一个文件如XML,而这个XML中记录了各个属性和值,在网络环境中,就可以作为一个传送的介质,这样,就可以实现类的远程调用。
重要的代码
RootDesignerSerializerAttribute a = TypeDescriptor.GetAttributes(root)[typeof(RootDesignerSerializerAttribute)] as RootDesignerSerializerAttribute;
Type t = host.GetType(a.SerializerTypeName);
CodeDomSerializer cds = Activator.CreateInstance(t) as CodeDomSerializer;
IDesignerSerializationManager manager = host.GetService(typeof(IDesignerSerializationManager)) as IDesignerSerializationManager;
CodeTypeDeclaration td = cds.Serialize(manager, root) as CodeTypeDeclaration;
在设计界面拖动的控件和设置的属性都通过对根设计器的序列化,被完全提取出来,成为一个CodeCompileUnit的主体部分。再增加构造函数和其它属性就可以了。
编译与生成
要编译的话,就必须传入数据CodeCompileUnit,然后使用CsharpCodeProvider,
VBCodeProvider就可以生成相应代码,也就是说,在设计的时候,不必要先指定使用何种语言,在设计完Form之后,再选定就可以了。因为,Form设计器最后产生的,是CodeCompileUnit,而不是代码。
在SampleDesignerLoader.cs类上,也提供了Build方法,这就是生成DLL或EXE文件,因为在Windows平台上,可以正常使用类集合的,就只要用这两个扩展名。只要使用CompilerParameters类和当前的程序类,传入CodeCompileUnit就可以了。之后,就只是生成选择了。详情请查看Build方法
出处:小作坊网ChakMan原创