C#.Net组件开发(高级篇) - 设计时在窗体设计器文件内生成组件的代码
C#.Net组件开发(高级篇) - 设计时在窗体设计器文件内生成组件的代码
在设计环境下设计组件和窗体设计器是很底层东西,技术非常复杂,水很深!刚学了点皮毛感觉入了门,特别将代码分享出来.在动手实验过程中遇到很多麻烦,因为没搞清这个实时设计的概念,还有这个窗体设计器会自动生成XXX.Designer.cs文件的代码,非常神奇的技术,也许将来对框架改进有帮助,所以想一探究竟.因为我不理解这个代码生成的机制,于是到处找文章,百度搜索关键字太烂了,基本上找不着我想要的,用Google勉强能找到一些文章,也不对口,东拼西凑,认真动手做实验,坚持了几天写了不少代码. 先讲下如何在窗体设计器文件内生成组件的代码,如要生成设计时的代码,参与的对象必须实现IComponent接口,比如往窗体上拖个Button, 打开XXX.Designer.cs文件查看代码: C# Code: private void InitializeComponent() { this.button1 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // button1 // this.button1.Location = new System.Drawing.Point(87, 75); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(75, 23); this.button1.TabIndex = 0; this.button1.Text = "button1"; this.button1.UseVisualStyleBackColor = true; // // frmTester // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(292, 266); this.Controls.Add(this.button1); this.Name = "frmTester"; this.Text = "frmTester"; this.ResumeLayout(false); } 可见自动生成了button1相关代码,最重要的是这句:this.Controls.Add(this.button1),将button1对象加入到窗体的控制列表中.在Controls.Add方法上点右键弹出菜单,选择Go to Definition查看源码: C# Code: public class Control : Component, IDropTarget, ISynchronizeInvoke, IWin32Window, IBindableComponent, IComponent, IDisposable { ...略... // Summary:} 可见Add方法接受Control参数,而Control类继承了实现IComponent接口的Component类. 好了,下面看我是如何自动生成button2的代码. 首先建立一个用于测试的组件,命名CSFrameworkComponent,类定义了一组属性(Attribute).给组件指定一个自定义的设计器CSFrameworkDesigner.我们使用CSFrameworkDesigner设计器生成按钮的代码. C# Code: [ToolboxBitmap(typeof(CSFrameworkComponent), "ComponentTest.bmp")] [DesignTimeVisible(true)] [Designer(typeof(CSFrameworkDesigner), typeof(IDesigner))] public partial class CSFrameworkComponent : Component { //窗体设计器的接口引用,当拖拉组件到窗体上,值由构造器传入. private IContainer _Designer; public CSFrameworkComponent() { } public CSFrameworkComponent(IContainer container) { _Designer = container; container.Add(this); } } //来源:C/S框架网(www.csframework.com) QQ:1980854898 自定义设计器CSFrameworkDesigner C# Code: public class CSFrameworkComponentDesigner : ComponentDesigner { private CSFrameworkComponent _CurrentComponent; public CSFrameworkComponentDesigner() : base() { // 添加菜单到右键菜单和智能标记中。 DesignerVerb V1 = new DesignerVerb("生成MyNodeComponent的设计时代码", new EventHandler(OnGenerateMyNodeComponentCode)); DesignerVerb V2 = new DesignerVerb("生成Button的设计时代码", new EventHandler(OnGenerateButtonCode)); DesignerVerb V3 = new DesignerVerb("www.CSFramework.com C/S框架网", new EventHandler(OnAbout)); this.Verbs.Add(V1); this.Verbs.Add(V2); this.Verbs.Add(V3); } private void OnAbout(object sender, EventArgs e) { MessageBox.Show("程序:Jonny Sun \r\n版权:www.CSFramework.com C/S框架网"); } private void OnGenerateMyNodeComponentCode(object sender, EventArgs e) { // //在窗体设计器代码中生成自定义MyNodeComponent组件的代码 // //取出窗体设计器 IDesignerHost host = (IDesignerHost)this.Component.Site.GetService(typeof(IDesignerHost)); //创建一个组件 MyNodeComponent node = (MyNodeComponent)host.CreateComponent(typeof(MyNodeComponent)); node.NodeName = "www.CSFramework.com"; node.ID = DateTime.Now.Millisecond; host.Container.Add(node);//在窗体设计器代码中生成代码 MessageBox.Show("已生成" node.NodeName "的代码!请打开frmTester.Designer.cs文件查看."); } public override void Initialize(IComponent component) { base.Initialize(component); _CurrentComponent = (CSFrameworkComponent)component; } private void OnGenerateButtonCode(object sender, EventArgs e) { // //在窗体上加入一个Button组件,host.RootComponent=Form // //取出窗体设计器 IDesignerHost host = (IDesignerHost)this.GetService(typeof(IDesignerHost)); IComponentChangeService c = (IComponentChangeService)this.GetService(typeof(IComponentChangeService)); Form form = (Form)host.RootComponent;//RootComponent: 根组件,指Form DesignerTransaction tran = host.CreateTransaction();//创建事务 //创建按钮组件 Button button = (Button)host.CreateComponent(typeof(Button)); button.Text = "www.CSFramework.com"; button.Location = new Point(50, 50); button.Size = new Size(150, 30); c.OnComponentChanging(form, null);//通知窗体正在新增控件服务 form.Controls.Add(button);//Form.Controls.Add, 生成持久化代码 c.OnComponentChanged(form, null, null, null);//通知窗体修改服务已完成 tran.Commit();//提交事务 MessageBox.Show("已生成" button.Name "的代码!请打开frmTester.Designer.cs文件查看."); } } //来源:C/S框架网(www.csframework.com) QQ:1980854898 完成组件和设计器的代码后重新编译程序,新建一个窗体,往窗体上拖一个CSFrameworkComponent组件,在组件上点右键如下图: frmTester.Designer.cs文件 扫一扫加作者微信
参考文档:
C#.Net组件开发 - 设计时使用自定义属性编辑器持久化对象 标签:C#.Net组件开发 - 设计时持久化对象数组 标签:C#.Net组件开发 - 属性窗体内显示自定义名称 标签:C#.Net组件开发 - 自定义设计器(ComponentDesigner) 标签:C#.Net组件开发 - 自定义设计器持久化对象的属性 标签:C#.Net组件开发 - 自定义属性编辑器持久化对象的属性 C#.Net组件开发(高级篇) - 自定义CollectionEditor编辑器 C#.Net组件开发(高级篇) - 开发复杂的设计时组件编辑器 C#.Net组件开发(高级篇) - 全部源码下载 C#.Net组件开发 - 使用Attach to Process实时调试设计器代码 C#.Net组件开发(高级篇) - 使用自定义TypeConverter生成设计时代码 DevExpress Winform 采用GridControl表格组件开发的会计凭证控件(C#源码) 软件开发与设计 - CMS内容管理系统-LeadWit CMS.NET 1.0.1 软件开发与设计 - CMS内容管理系统-[CMS程序]捷派网站管理系统(.Net) v2.01数据库表结构 软件开发与设计 - CMS内容管理系统-[CMS程序]逐迹工作室.NET(C#)内容管理系统 v1.1
其它资料:
什么是C/S结构? | C/S框架核心组成部分 | C/S框架-WebService部署图 | C/S框架-权限管理 | C/S结构系统框架 - 5.1旗舰版介绍 | C/S结构系统框架 - 功能介绍 | C/S结构系统框架 - 产品列表 | C/S结构系统框架 - 应用展示(图) | 三层体系架构详解 | C/S架构轻量级快速开发框架 | C/S框架网客户案例 | WebApi快速开发框架 | C/S框架代码生成器 | 用户授权注册软件系统 | 版本自动升级软件 | 数据库底层应用框架 | CSFramework.CMS内容管理系统 | |