文档章节

.Net开发笔记(十一) 设计时(Design-Time)和运行时(Run-Time)的区别

IT周见智
 IT周见智
发布于 2015/06/05 17:18
字数 2109
阅读 10
收藏 0

设计时和运行时的概念网上的中文资料很少,如果不是做第三方组件开发的或者跟设计器开发有关的,几乎用不到这些概念。为了迎合之前几篇博客,我想有必要说一下它两的概念和区别,以及用在什么地方。博客好久没更新,比较忙。

首先,我个人认为“设计时”和“运行时”是针对组件而言的(包括控件),也就是说,一个组件可以处在“运行时”也可以处在“设计时”两个状态,从字面上的意思来看,“设计时”当然是指处在开发阶段,开发人员在设计器中开发组件的时候,而“运行时”指程序处在运行阶段,比如一个button控件,在设计器中的窗体中时,它就处于“设计时”,当程序运行起来之后,这个button还是在窗体中,但它处于“运行时”了。呵,字面上的意思很好理解,那么这两个状态到底有什么用呢?也就是说,微软为什么规定组件有两个状态?想要了解这个问题的答案,我们先得清楚“可视化设计器”(比如VS  IDE)的作用,简单的总结一下:可视化设计器提供一个WYSIWYG(所见即所得)的开发环境,为开发人员提供一个更直观的操作平台。可是,就是这么两句简单的话,却迷惑了多少人。我们来看一张图:

如图所示,任何组件都是可以放在“设计器”中设计的(详见前面几篇博客),也就是说,组件具备“可视化设计”的特性,开发人员通过向设计器中添加组件,就可以快速地设计出一个类型(Form1),然后生成代码文档,保存。整个过程需要注意一下几点:

  • 组件具备“可视化设计”的特性,这里的设计并不代表我们可以改变原有组件的代码,比如向设计器中拖进一个Button控件,默认命名“button1”,接着我们编辑它的属性、绑定事件等等,这些所有的操作都只发生在button1身上,并不会影响原来Button类代码。换句话说,只设计“组件实例“。
  • 开发人员向设计器中添加组件(包括控件),设计器中的组件都是“实例”,也就是说图中的label1、textbox1、button1这些东西都是实实在在地“控件实例”,什么叫“控件实例”?就是说它们都有自己的句柄(Handle)、窗口过程(WndProc)(控件即窗体,窗体即控件,窗体都有句柄和窗口过程,不清楚的请看前面的博客),如果诸位不相信,可以用Spy++查看设计器中的这些控件,可以查找出它们的Handle以及其他信息。关于这一点,我前面博客已经解释过,这里我再提一下。
  • 不管我们怎么操作设计器,我们在设计器中看到的东西确实跟程序运行后的界面大概差不多,但是需要明白的是,设计器中的东西全部都是“虚”的,为什么说它是虚的?因为我们一关闭设计器之后,设计器中的东西全部销毁了,而真正有用的东西就是图中③生成的代码文档!对,你没有看错,我更没有写错,代码文档才是我们最终需要的东西,我们可以将它编译生成exe或者dll文件,不是吗?
  • 接3),我们可以一句话来概括一下“设计器”的作用:为了更快的生成想要的代码。是的,设计器最终的目的就是为开发人员快速生成代码,换句话说,假如没有设计器,开发人员完全可以自己去写代码(比如图中的Form1.cs和Form1.Designer.cs),可是没有哪个sb会这样去做,因为那样实在太麻烦了。
  • 我们将生成的代码文档编译生成exe文件,运行之,我们会看见什么?毫无疑问,我们会看见与设计器中差不多类似的界面,有一个label、一个textbox、一个button。这个是为什么?因为生成的代码都是由设计器生成的,我们拖进去一个Label,设计器就会生成类似如下的代码:
1 Label  label1 = new Label();
2 
3 label1.Location = new Point(10,10);
4 
5 label1.Text = “label1”;
6 
7 this.Controls.Add(label1);

//大概类似这样,可能不相同

同理,textbox1和button1也一样。如果我们在属性列表中修改label1的Text属性为“test”,那么,立即有这样的代码生成:

label1.Text = “test”;

注意,以上自动生成的代码都在InitializeComponent方法中,我们将生成的代码编译运行,当然会按照原来设计时的样子一一还原。

如果看懂以上5点的童鞋,那么基本上就能理解本篇博客所要说明的问题了。我们再来回忆一下文章开始提出来的问题:组件为啥要有两个状态,设计时(Design-Time)和运行时(Run-Time)?答案在2)和5)中,已经说过,设计器中的任何组件都是实例,换句话说,你往设计器中拖放组件的时候,会调用它的构造方法,如果该组件恰好是一个控件,那么肯定会激发它的Load事件,当它在设计器中重绘时,肯定会激发它的Paint事件等等等。也就是说,如果我自定义一个控件:

1 MyControl:UserControl
2 {
3 protected override OnLoad(EventArgs e)
4 {
5      MessageBox(“加载了!”);
6 }
7 }
View Code

本来设计这个自定义控件的开发人员想让控件加载时,弹出一个消息框,现在问题来了,使用这个自定义控件的coder,只要将该控件拖进设计器时,就会弹出一个MessageBox,毫无疑问,这不是我们希望的。如下图:

这只是一个简单例子,如果我们在开发第三方组建时,需要在某些场合进行IO操作、访问数据库或者操作注册表等等,那么就有必要考虑这些会不会在设计器中发生,比如修改一下上面的代码:

1 MyControl:UserControl
2 {
3 protected override OnLoad(EventArgs e)
4 {
5      //操作注册表
6      //连接数据库
7 }
8 }
View Code

问题就显而易见了,只要你将该控件拖进设计器,那么就会发生“操作注册表”或者“连接数据库”这样的行为。

想要解决以上问题,微软就提出来了“设计时”和“运行时”的概念,其实就我个人理解,同一个组件,它出现在设计器中,它就是处于“设计时”,否则它就是处于“运行时”,每个组件都有一个DesinMode属性,如果该属性为true,那么它就是处于“设计时”,否则,它就是处于“运行时”。(注:该方法判断不太准确,只适合大部分场合,使用所有场合的判断方法现在不必提及

那么,原有代码就可以修改为:

 1 MyControl:UserControl
 2 {
 3 protected override OnLoad(EventArgs e)
 4 {
 5 if(!DesignMode)  //如果不处于“设计时”
 6 {
 7        //操作注册表
 8        //连接数据库
 9     }
10 }
11 }
View Code

问题完美解决。设计时和运行时的概念,就像同一个人,出生在官宦之家,那么他就是“官二代”,如果出生在普通家庭,那么他很有可能是所谓的“屌丝”。官二代和屌丝有很大的区别,就像设计器中的Button和运行期间的Button,差别很大。

另外,至于为什么设计器中的组件与运行时的组件能有不同的表现,比如设计器中的组件可以通过属性列表编辑它的属性,可以改变它的位置、大小等等等等,甚至为什么会自动生成代码,这些东西都属于设计器所必须具备的功能,本篇文章不讨论。

代码为word中所写,如有错误,望见谅!希望对诸位有帮助。

© 著作权归作者所有

共有 人打赏支持
IT周见智

IT周见智

粉丝 10
博文 61
码字总数 185891
作品 0
西青
Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

本章节,我将通过示例介绍如何搭建mvvmlight开发环境。示例中的我会针对wpf代码进行介绍,SL下有区别的地方我会注明,下载示例中会同时包含WPF和SL源代码,但是只会提供VS2010版本的示例程序...

鉴客
2011/12/31
1K
0
[Github项目]C++核心指南

C++作为一门多范型的语言,有灵活性。再加上C++的一些技巧,一些坑,很多公司都有自己的C++编码规范。这些规范一般都是建议什么该用,什么不该用,怎么去命名之类。没有提纲挈领地给出一个完...

开源中国驻成都办事处
2015/10/14
350
0
LNK4098: 默认库“MSVCRT”与其他库的使用冲突

LNK4098: 默认库“MSVCRT”与其他库的使用冲突 修改的方法:在项目属性中,在连接器-输入选项中,在忽略特定库中添加相应的库,具体添加那些苦请参照下面的表格。 下面的内容为转载,原文链接...

IMGTN
2012/12/06
0
0
奇异递归模板模式( Curiously Recurring Template Pattern,CRTP)1

1.CRTP介绍 奇异递归模板模式(curiously recurring template pattern,CRTP)是C++模板编程时的一种惯用法(idiom):把派生类作为基类的模板参数。更一般地被称作F-bound polymorphism,是...

gfsfg8545
2017/06/25
0
0
《Linux内核设计与实现》读书笔记 - 目录 (完结)

《Linux内核设计与实现》读书笔记 - 目录 (完结) 读完这本书回过头才发现, 第一篇笔记居然是 2012年8月发的, 将近一年半的时间才看完这本书(汗!!!). 为了方便以后查看, 做个《Linux内核设计...

你的猫大哥
01/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Web系统大规模并发:电商秒杀与抢购

一、大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常...

xtof
今天
1
0
代码质量管理平台-sonarqube

在工作中,往往开发的时候会不怎么注重代码质量的人很多,存在着很多的漏洞和隐患等问题,sonarqube可以进行代码质量的审核,而且十分的残酷。。。。。接下来我们说下怎么安装 进入官网下载:...

落叶清风
今天
6
0
在Ubuntu安装和配置Sphinx

Ubuntu系统默认是配置有sphinx的,先检查一下,别多此一举。。。。。 在开始本指南之前,您需要: 一个Ubuntu 16.04服务器。 sudo的一个非root用户,您可以通过以下设置本教程 。 安装在服务...

阿锋zxf
今天
1
0
Qt编写输入法V2018超级终结版

对于qt嵌入式linux开发人员来说,输入法一直是个鸡肋问题,要么不支持实体键盘同步,要么不能汉字输入,要么不支持网页输入等,这几年通过陆续接触大量的各种输入法应用场景客户,得到真实需...

飞扬青云
今天
2
0
TypeScript基础入门之高级类型的多态的 this类型

转发 TypeScript基础入门之高级类型的多态的 this类型 高级类型 多态的this类型 多态的this类型表示的是某个包含类或接口的子类型。 这被称做F-bounded多态性。 它能很容易的表现连贯接口间的...

durban
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部