.Net开发笔记(九)自定义窗体设计器

简介:

其实本文标题说得有点大,一个窗体设计器包含的功能实在是太多而且非常复杂,网上有很多地方也讲到这方面的内容,不过基本上都是E文,http://www.codeproject.com/Articles/24385/Have-a-Great-DesignTime-Experience-with-a-Powerful该处作者实现了一个简单的Form Designer,而且附有源码,不过也只是点到为止,功能不多,还有一个老外的开源项目http://www.icsharpcode.net/OpenSource/SD/,基本上涵盖了界面设计、生成代码、编译、调试等功能,能和VS IDE有一拼,源码压缩包有几十M,复杂度可想而知,我大概看了一下这两个的源码结构,基本上都是利用微软FCL中提供的接口、类来实现的,它们主要存在System.ComponentModel,Design命名空间中,比如DesignSurface、IDesignerHost、ISelectionService等,诸位也知道,微软的东西用起来很方便,理解起来嘛,那是相当的困难,因为你根本不知道为啥要那么搞,所以本篇文章我打算试着从底层来说明“窗体可视化设计”到底是个什么东西,诸位看官如果之前了解也不妨看看,不了解的话也没事,基本上涉及到的都是平时用到的技术,不涉及到System.ComponentModel,Design中的任何东西。文章最后附带Demo源码下载地址。

我不知道窗体设计器对诸位来说是个什么样的概念,从开始学习可视化编程时,我们就开始接触了它,就我来说,用过VC6.0、VB以及现在的VS,基本上都是一样,在界面上拖拖控件,写写事件处理程序,编译后就能运行一个简单功能的Windows桌面应用程序了,但是,有以下疑问(Winform为例):

  1. 在新建一个Windows窗体时,设计器中默认出现的窗体是个什么东西?是真实实例化的一个Form(或其派生类)对象,还是其他替代品?
  2. 从工具箱中向窗体上拖一个Button控件,是一个什么样的过程?
  3. 类似1,拖进的Button控件是个什么东西?是真是实例化的一个Button类对象,还是其他替代品?
  4. 在设计器中选中一个控件(或者窗体),周围出现的方框是什么东西?鼠标又是怎么改变控件的位置和大小?
  5. 怎样选中多个控件,让其按照某一规则自动对齐?怎样实现设计器中的“剪切”、“粘贴”等菜单?

暂时先列这么几个问题,其实还有很多,只是其他的本文没有给出解释,比如双击Button按钮时,怎么自动生成事件代码?最重要的是,怎样根据设计的界面生成代码?这些问题其实利用.net中提供的类都能实现,只是不太容易去探究它底层的具体实现细节。下面我就来原汁原味地解释一下以上提出的疑问,Demo中我用自己的方法从底层开始实现了跟常用设计器效果基本一样的功能,当然我不保证.net类库中的类底层就是像我解释的这样去实现的,因为我也没看该部分类的源码,呵呵。

以下就是解释:

  1. 设计器中的默认窗体是真实实例化的一个Form(或其派生类)对象,也就是说,它跟桌面左下角“开始”按钮一样,是一个真实存在的控件(窗体即控件,控件即窗体,详见我前面的博客),至于为什么,这个很好解释,因为如果不是真实存在的控件,是不可能通过属性窗口(一般为PropertyGrid控件)来动态显示和修改它的属性。另外,诸位可以用Spy++查看设计器中的窗体和控件,你会发现能看到他们的句柄(Handle)。
  2. 当用户(Programmer)从工具箱向窗体中拖一个Button控件时,对于设计器来说,做的事情很简单:实例化一个控件,将其加到设计器中的默认窗体中,设置属性窗口中的PropertyGrid.SelectedObject = 实例化的控件。
  3. 跟1相同。其实这时候出现了一个问题,既然1中3中说到,设计器中的窗体和控件都是像桌面左下角“开始”按钮一样真实存在的,那么它应该能接受用户输入吧?!比如鼠标点击、键盘输入等,可是如我们所见,所有的设计器中的窗体和控件几乎都不能按照正常方式去响应用户输入,这是为什么?其实,我们的眼睛骗了我们,因为设计器中不只是窗体和控件,在它们上面还有一个透明的遮罩层,看一幅图:

图1

如你们所见,整个设计器可以分为三层,底层的灰色部分可以看作整个设计器的容器,中间层的蓝色部分就是设计器中的默认窗体,所有拖进设计器中的控件都是放在蓝色部分中,在蓝色部分上面,有一层透明的遮罩层(用橘黄色方框表示),大小跟底层的灰色部分一致,在用户(Programer)看来,最上面的遮罩层是“不存在”的,但是事实上,所有的鼠标键盘操作都被遮罩层拦截,由它进行处理,因此,中间层的窗体和控件不会接受任何用户输入。注:中间层的蓝色部分和最上面的橘黄色部分都属于底层灰色部分,如果把它们都看做控件,那么蓝色部分和橘黄色是平行关系,都属于灰色部分的子控件,只是Z轴顺序不同(Demo中的源码有所体现)。

     4.既然最上面有一个透明的遮罩层,那么当选中一个控件时,周围出现的选中方框可以把它画在这个遮罩层上,任何时候遮罩层中的方框跟中间层的选中控件相对应,保持一致,也就是说,无论方框大小还是位置,都跟中间层的选中控件一样,让人看起来,它两重合  ( 虽然不在同一个层面)。鼠标操作的是顶层的方框,中间层的控件跟着移动、变大、变小。

     5.在设计器中,如果选中多个控件,就会出现多个选中方框,道理一样,所有的选中方框都在最顶层,每一个方框都与中间层的某一控件相对应,操作跟4中一样。复制时,可以将选中控件的完整名称、属性、以及属性值收集起来存放在ClipBoard中,粘贴时,根据 完整名称新建控件,将属性值赋予新建控件,将其加到中间层。

以上就是从底层开始解释一个窗体设计器的简单原理,在图1中,底层灰色部分DesignerControl是一个UserControl,HostFrame是一个控件容器(Form),Overlayer也是一个透明的UserControl,Recter为虚线效果的选中框,这些名称分别与Demo中的源码对应,诸位可以对照参考。

另外,我说几个关键点:

  • 透明控件的实现
View Code
  • 当移动或者改变顶层的方框时,不要让中间层的控件刷新的方法,就是过滤掉中间层控件的WM_PAINT消息,用到了System.Windows.Forms.IMessageFilter接口,该接口中有一PreFilterMessage方法,专门用来过滤需要忽略的Windows消息,具体实现如下:
View Code

使用时,用Application.AddMessageFilter()方法就可以,MSDN上对该方法有一个解释,大概意义是说此操作只对当前UI线程有效,也就是说如果一个应用程序有两个或者多个UI线程,只能过滤当前UI线程中的某一消息。当然这个不是重点,我只是简单的提一下,有关Windows消息以及WInform中的消息流动问题,请参考我之前的博客。

  • 选中方框就是一个普通的类,代码如下:
View Code

其余的都很简单,用到的都是简单技术,详细请参考源码。XP .net3.5测试通过,源码下载地址:http://download.csdn.net/detail/xiaozhi_5638/5185939。源码中没有剪切、复制、自动对齐等功能。

上一张Demo效果图:

图2

希望有帮助,O(∩_∩)O~。感觉本文对自己有用的朋友,给个“推荐”或者建议啥的都是可以滴,非常感谢~

 

作者:周见智 
出处:http://www.cnblogs.com/xiaozhi_5638/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

标签:  c#Winform

本文转自周见智博客博客园博客,原文链接:http://www.cnblogs.com/xiaozhi_5638/archive/2013/03/27/2984086.html,如需转载请自行联系原作者
目录
相关文章
|
11月前
|
人工智能 芯片
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
D1net阅闻|OpenAI员工疯狂暗示,内部已成功开发ASI?被曝训出GPT-5但雪藏
|
9月前
|
SQL 小程序 API
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
378 0
|
JSON 安全 API
.net 自定义日志类
在.NET中,创建自定义日志类有助于更好地管理日志信息。示例展示了如何创建、配置和使用日志记录功能,包括写入日志文件、设置日志级别、格式化消息等。注意事项涵盖时间戳、日志级别、JSON序列化、线程安全、日志格式、文件处理及示例使用。请根据需求调整代码。
220 13
|
缓存 算法 安全
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
精选10款C#/.NET开发必备类库(含使用教程),工作效率提升利器!
486 12
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
231 9
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
205 8
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
201 7
|
网络协议 C#
基于.NET WinForm开发的一款硬件及协议通讯工具
基于.NET WinForm开发的一款硬件及协议通讯工具
163 7
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
434 5
|
机器学习/深度学习 人工智能 物联网
.NET 技术:引领未来开发潮流
.NET 技术以其跨平台兼容性、高效的开发体验、强大的性能表现和安全可靠的架构,成为引领未来开发潮流的重要力量。本文深入探讨了 .NET 的核心优势与特点,及其在企业级应用、移动开发、云计算、人工智能等领域的广泛应用,展示了其卓越的应用价值和未来发展前景。
246 5