C#中 paint()與Onpaint()的區(qū)別
protected virtual OnPaint(PaintEventArgs e)
{
if(paint != null)
{
paint(this,e);
}
}
如果直接重寫onpaint,paint就會失效;這樣就不會失效:
protected override OnPaint(PaintEventArgs e)
{
base.OnPaint(e); //自己的代碼
}
(一)重繪時(shí)候經(jīng)常會用到OnPaint()和Paint,它們有什么區(qū)別呢?
1.OnPaint方法是對一個(gè)控件來說的;而Paint事件是對一個(gè)控件對象來說的。它們中前者相當(dāng)于是類的一個(gè)成員函數(shù),而后者相當(dāng)于是類的一個(gè)函數(shù)指針類型的變量(會因?qū)ο蟮牟煌煌?nbsp;
2.OnPaint方法引發(fā)Paint事件,所以重寫OnPaint方法,一定要調(diào)用base.OnPaint,否則就不會引發(fā)Paint事件了。OnPaint原形應(yīng)該類似以下形式(從中便可以看出):
protected virtual void OnPaint(PaintEventArgs e)
{
if (this.Paint != null)
{
this.Paint(this,e);
}
}
3.從實(shí)例中觀察二者調(diào)用順序
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, 10, 10);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);//引發(fā)Paint事件處理(處理該事件時(shí)候調(diào)用Form1_Paint方法)
..........
}
Form1_Paint()只是處理Paint事件的方法,也可將它的四行代碼在OnPaint方法中寫,此時(shí)可以不寫base.OnPaint(e),即不引發(fā)事件處理,也可達(dá)到同樣的效果。
(二)那么應(yīng)分別在什么情況下使用它們呢?
1.如果想對所有控件都按照某種固定的方式顯示,如:自己寫控件時(shí),則需要修改重載控件的OnPaint方法;而如果僅僅在某個(gè)環(huán)境下,對某個(gè)對象要做不同的顯示,則只需在其的Paint事件中做即可。
2.在實(shí)現(xiàn)派生類的時(shí)候,遵循 C# 原則35:選擇重寫函數(shù)而不是使用事件句柄。
許多.net類庫中的類都提供了兩種不同的處理事件句柄的方法。既可以為其添加事件,也可以重寫其基類的事件抽象方法。在實(shí)現(xiàn)派生類的時(shí)候,更好的選擇是重寫基類中的抽象方法。
因?yàn)檫@樣,一旦事件句柄拋出異常,不會再有其他的事件句柄被調(diào)用。這避免了一些錯(cuò)誤代碼繼續(xù)被調(diào)用而引發(fā)的問題。通過重寫受保護(hù)的虛方法,我們的句柄可以 第一個(gè)被調(diào)用?;愔刑摵瘮?shù)負(fù)責(zé)其他相關(guān)句柄的調(diào)用。這意味著如果需要調(diào)用那些事件句柄(一般來說是需要的),就要調(diào)用基類的虛函數(shù)。在有些特殊情況下我 們需要替換基類的默認(rèn)行為,可能不需要調(diào)用任何原有的事件句柄。雖然我們不能保證所有的事件句柄都被執(zhí)行,因?yàn)槠淇赡軙伋霎惓?,但是我們可以保證派生類 的行為是正確的。
使用override比添加事件句柄高效的多。在 條款 22中展示了System.Windows.Forms.Control類是如何存儲句柄時(shí)間并將其對應(yīng)到每一個(gè)事件的。這種事件機(jī)制由于要檢查事件句柄將造成更多的消耗。事件句柄列表中的每個(gè)方法都需要執(zhí)行。相比重寫虛方法,通過事件處理會消耗更多的時(shí)間。
此外,重寫虛方法只需要維護(hù)一個(gè)函數(shù)就可以達(dá)到檢查和修改的目的,代碼更清晰。而事件機(jī)制需要兩個(gè)維護(hù)點(diǎn):事件句柄函數(shù)和事件綁定代碼。其中任何一點(diǎn)都可能造成整體功能上的失敗。一個(gè)函數(shù)顯然要簡單些。
相關(guān)文章
C#創(chuàng)建數(shù)據(jù)庫及附加數(shù)據(jù)庫的操作方法
這篇文章主要介紹了C#創(chuàng)建數(shù)據(jù)庫及附加數(shù)據(jù)庫的操作方法,涉及C#針對數(shù)據(jù)庫常見的創(chuàng)建、添加、連接等操作技巧,需要的朋友可以參考下2016-06-06舉例講解C#編程中對設(shè)計(jì)模式中的單例模式的運(yùn)用
這篇文章主要介紹了C#編程中對設(shè)計(jì)模式中的單例模式的運(yùn)用,單例模式在.NET框架的相關(guān)開發(fā)中也被經(jīng)常用到,需要的朋友可以參考下2016-02-02C#進(jìn)行文件讀寫、創(chuàng)建、復(fù)制、移動、刪除的方法
這篇文章主要介紹了C#進(jìn)行文件讀寫、創(chuàng)建、復(fù)制、移動、刪除的方法,涉及C#針對文件操作的常用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03