C#中Form的Paint事件响应方法与重载虚方法OnPaint()的区别
Form_Paint()方法是Paint事件的响应方法,OnPaint是可重载的虚方法,OnPaint方法是调用Paint事件的,用哪一个,效果是一样,就看那一个方便了内部是这样实现的:
protected virtual OnPaint(PaintEventArgs e)
{
if(paint != null)
{
paint(this,e);
}
}
如果直接重写虚方法OnPaint,Paint事件就会失效;这样就不会失效:
protected override OnPaint(PaintEventArgs e)
{
base.OnPaint(e); //自己的代码
}
(一)重绘时候经常会用到OnPaint()和Paint,它们有什么区别呢?
1.OnPaint方法是对一个控件来说的;而Paint事件是对一个控件对象来说的。它们中前者相当于是类的一个成员函数,而后者相当于是类的一个函数指针类型的变量(会因对象的不同而不同)。
2.OnPaint方法引发Paint事件,所以重写OnPaint方法,一定要调用base.OnPaint,否则就不会引发Paint事件了。OnPaint原形应该类似以下形式(从中便可以看出):
protected virtual void OnPaint(PaintEventArgs e)
{
if (this.Paint != null)
{
this.Paint(this,e);
}
}
3.从实例中观察二者调用顺序
private void Form1_Paint(object sender, PaintEventArgs e)
{
test t = new test();
t.AntiAlias = true;
t.SetColor(test.eShapeColor.Circle1FillColor, Color.DarkCyan);
e.Graphics.DrawImageUnscaled(t.Image, , );
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);//引发Paint事件处理(处理该事件时候调用Form1_Paint方法)
..........
}
Form1_Paint()只是处理Paint事件的方法,也可将它的四行代码在OnPaint方法中写,此时可以不写base.OnPaint(e),即不引发事件处理,也可达到同样的效果。
(二)那么应分别在什么情况下使用它们呢?
1.如果想对所有控件都按照某种固定的方式显示,如:自己写控件时,则需要修改重载控件的OnPaint方法;而如果仅仅在某个环境下,对某个对象要做不同的显示,则只需在其的Paint事件中做即可。
2.在实现派生类的时候,遵循 C# 原则35:选择重写函数而不是使用事件句柄。
许多.net类库中的类都提供了两种不同的处理事件句柄的方法。既可以为其添加事件,也可以重写其基类的事件抽象方法。在实现派生类的时候,更好的选择是重写基类中的抽象方法。
因为这样,一旦事件句柄抛出异常,不会再有其他的事件句柄被调用。这避免了一些错误代码继续被调用而引发的问题。通过重写受保护的虚方法,我们的句柄可以 第一个被调用。基类中虚函数负责其他相关句柄的调用。这意味着如果需要调用那些事件句柄(一般来说是需要的),就要调用基类的虚函数。在有些特殊情况下我 们需要替换基类的默认行为,可能不需要调用任何原有的事件句柄。虽然我们不能保证所有的事件句柄都被执行,因为其可能会抛出异常,但是我们可以保证派生类 的行为是正确的。
使用override比添加事件句柄高效的多。在 条款 22中展示了System.Windows.Forms.Control类是如何存储句柄时间并将其对应到每一个事件的。这种事件机制由于要检查事件句柄将造成更多的消耗。事件句柄列表中的每个方法都需要执行。相比重写虚方法,通过事件处理会消耗更多的时间。
此外,重写虚方法只需要维护一个函数就可以达到检查和修改的目的,代码更清晰。而事件机制需要两个维护点:事件句柄函数和事件绑定代码。其中任何一点都可能造成整体功能上的失败。一个函数显然要简单些。
其它名词解释:
句柄 : 句柄,是整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄。
重写 : 当一个子类继承一父类,而子类中的方法与父类中的方法的名称,参数个数、类型都完全一致时,就称子类中的这个方法重写了父类中的方法。
函数 : 函数(function),最早由中国清朝数学家李善兰翻译,出于其著作《代数学》。之所以这么翻译,他给出的原因是“凡此变数中函彼变数者,则此为彼之函数”,也即函数指一个量随着另一个量的变化而变化,或者说一个量中包含另一个量。
代码 : 代码就是程序员用开发工具所支持的语言写出来的源文件,是一组由字符、符号或信号码元以离散形式表示信息的明确的规则体系。代码设计的原则包括惟一确定性、标准化和通用性、可扩充性与稳定性、便于识别与记忆、力求短小与格式统一以及容易修改等。 源代码是代码的分支,某种意义上来说。
C#中Form的Paint事件响应方法与重载虚方法OnPaint()的区别的更多相关文章
- 【转载】Asp.Net中应用程序的事件响应次序
Asp.Net应用程序事件响应次序是指Application事件的相应次序,涉及到的事件包括Application_Start事件.BeginRequest事件.AuthenticateRequest ...
- .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]
方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...
- C#方法的重载和方法的可变参数
方法的重载 1.方法重载的前提:方法名称必须一样 2.构成重载的条件:参数不一样(参数数量不一样,参数类型不一样) 方法的可变参数 1.可变参数的值的数量可以是0到多个. 2.可变参数调用的时候,没有 ...
- Partial(部分方法,局部方法),virtual(虚方法),abstract(抽象方法)
Partial 部分方法顾明思议是方法的一部分,不完整的,在ide编译时候,会将所有部分方法加载到一起统一编译,如果分部方法没有被实现,编译器就不会.对他们进行编译. 局部类型的限制 (1) 局部类型 ...
- C#中控件Control的Paint事件和OnPaint虚函数的区别
句柄 : 句柄,是整个Windows编程的基础.一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按 ...
- 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- C#z中的虚方法,抽象类
1.虚方法 我在这动物类中定义了一个虚方法 Dosth class Animal { public int Aid; public string Name; public void SetAid(in ...
- 【原创】SystemVerilog中的多态和虚方法
封装可以隐藏实现细节,使代码模块化,继承可以扩展已经存在的代码模块,目的都是为了代码重用.多态是为了实现接口的重用.在SystemVerilog中,子类和父类之间多个子程序使用同一个名字的现象称为Sy ...
- Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息
Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...
随机推荐
- Effective C++ .09 不在构造和析构过程中调用virtual函数
看过C++对象模型的话就可以知道,在构造基类时,完整的vtable没有建立起来(表项没有被相应的子类函数替换),因而无法调用到子类的函数(即构造函数中的virtual函数是本类里的方法,不是virtu ...
- php+mysql+jquery日历签到
在网站开发过程中我们会经常用到签到功能来奖励用户积分,或者做一些其他活动.这次项目开发过程中做了日历签到,因为没有经验所有走了很多弯路,再次记录过程和步骤. 1.日历签到样式: 2.本次签到只记录本月 ...
- css以前忽略的一些知识点(知识体系搭建)
一.选择器 基本选择器: 通用元素选择器 标签选择器 类选择器 id选择器 组合选择器: 多元素组合选择器 后代元素选择器 子代元素选择器 毗邻元素选择器 属性选择器: [title] & P ...
- var a =10 与 a = 10的区别
学习文章------汤姆大叔-变量对象 总结笔记 变量特点: ①变量声明可以存储在变量对象中.②变量不能直接用delete删除. var a =10 与 a = 10的区别: ①a = 10只是为全局 ...
- Python基础-简介二
一.变量类型 变量存储在内存中的值.这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型,这些 ...
- Linux基础之-shell script(变量,运算符,流程控制,函数)
一.shell script Shell 脚本(shell script),是一种为shell编写的脚本程序.业界所说的shell通常都是指shell脚本,但读者朋友要知道,shell和shell s ...
- ASP.NET内容页中访问母版页中的对象
在ASP.NET2.0开始,提供了母版页的功能.母版页由一个母版页和多个内容页构成.母版页的主要功能是为ASP.NET应用程序中的页面创建相同的布局和界面风格.母版页的使用与普通页面类似,可以在其中放 ...
- WinAPI: GetCurrentThread、GetCurrentThreadId、GetCurrentProcess、GetCurrentProcessId
原文:http://www.cnblogs.com/del/archive/2008/03/10/1098311.html {返回当前线程的虚拟句柄} GetCurrentThread: THandl ...
- asp.net ashx导出excel到前台
最近有一个项目使用以前的ashx,不能使用FileResult,只有通过response返回拼接好的字符串.但是通过查阅资料拼接的字符串总是提示文件格式不匹配,虽然能正常打开,但是体验很不好,在此总结 ...
- linux第一个C语言和sh脚本
linux第一个C语言 $ gedit hello_world.c #include <stdio.h> int main(void) { printf("hello world ...