




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第Winform控件優(yōu)化Paint事件實現(xiàn)圓角組件及提取繪制圓角的方法button2.FlatAppearance.BorderSize=0;
//button2.FlatAppearance.BorderColor=SystemColors.ButtonFace;
button2.FlatAppearance.MouseDownBackColor=Color.Transparent;
button2.FlatAppearance.MouseOverBackColor=Color.Transparent;
button2.FlatAppearance.CheckedBackColor=Color.Transparent;
button3.Paint+=Button1_Paint;
button3.FlatStyle=FlatStyle.Flat;
button3.FlatAppearance.BorderSize=0;
//button3.FlatAppearance.BorderColor=SystemColors.ButtonFace;
button3.FlatAppearance.MouseDownBackColor=Color.Transparent;
button3.FlatAppearance.MouseOverBackColor=Color.Transparent;
button3.FlatAppearance.CheckedBackColor=Color.Transparent;
label1.Paint+=Label1_Paint;
label1.BackColor=Color.Transparent;
privatevoidLabel1_Paint(objectsender,PaintEventArgse)
varl=(Label)sender;
//e.Graphics.DrawRoundRectAndCusp(e.ClipRectangle,18,Color.FromArgb(180,200,210),Color.FromArgb(120,120,100));//不推薦
e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,l.Width,l.Height),18,Color.FromArgb(180,200,210),Color.FromArgb(120,120,100));
privatevoidButton1_Paint(objectsender,PaintEventArgse)
varbtn=(Button)sender;
e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,btn.Width,btn.Height),18,Color.FromArgb(0,122,204),Color.FromArgb(8,39,57));
((Button)sender).NotifyDefault(false);//去除窗體失去焦點時最新激活的按鈕邊框外觀樣式
privatevoidPanel1_Paint(objectsender,PaintEventArgse)
varpanel=senderasPanel;
varrect=e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,panel.Width,panel.Height),18,Color.FromArgb(90,143,0),Color.FromArgb(41,67,0),true,rectAlign);
privatevoidPanel2_Paint(objectsender,PaintEventArgse)
varpanel=senderasPanel;
varrect=e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,panel.Width,panel.Height),18,Color.FromArgb(113,113,113),Color.FromArgb(0,0,0));
}
查看效果:
在Paint事件中不需要調(diào)用base.OnPaint(e);,只有在繼承控件重寫OnPaint方法時,才應(yīng)該(在函數(shù)方法開始時)調(diào)用base.OnPaint(e);。
提取繪制圓角矩形和旁邊小尖角的代碼為擴展方法
介紹
下面是提取的擴展方法,對源代碼進行了修改和優(yōu)化。
1、可繪制漸變背景色、指定背景色、指定畫刷繪制的背景;可指定漸變背景的方向2、指定圓角半徑的繪制,如果半徑小于等于0,將繪制直角矩形。3、指定三角小尖,默認不繪制;指定三角小尖的位置,可供八個位置選擇4、三角小尖的大小,目前感覺作為參數(shù)傳遞不夠靈活,如果需要調(diào)整可直接從代碼中修改,主要修改部分為:
//尖角的大小默認為開始位置為_radius底邊為20,高度為13的等腰三角形
varcuspHemlineStart=_radius;
varcuspHemlineLength=20;
varcuspHeight=13;
擴展方法
擴展方法代碼如下,將其放在namespaceSystem.Drawing.Drawing2D下,可直接方便的從Graphics對象調(diào)用。
///summary
///繪制可漸變的圓角矩形,并指定是否有三角小尖及其位置
////summary
///paramname="g"/param
///paramname="rectangle"矩形區(qū)域/param
///paramname="_radius"圓角半徑/param
///paramname="begin_bgcolor"背景漸變開始色/param
///paramname="end_bgcolor"背景漸變結(jié)束色/param
///paramname="cusp"是否有三角小尖,默認無/param
///paramname="rectAlign"三角小尖的位置,默認右上/param
///paramname="gradientMode"漸變模式,默認垂直方向漸變/param
publicstaticvoidDrawRoundRectAndCusp(thisGraphicsg,Rectanglerectangle,int_radius,Colorbegin_bgcolor,Colorend_bgcolor,boolcusp=false,RectangleAlignrectAlign=RectangleAlign.RightTop,LinearGradientModegradientMode=LinearGradientMode.Vertical)
////抗鋸齒等模式在Graphics外層自定義設(shè)置
//g.SmoothingMode=SmoothingMode.AntiAlias;
//漸變填充
LinearGradientBrushlinearGradientBrush=newLinearGradientBrush(rectangle,begin_bgcolor,end_bgcolor,gradientMode);
g.DrawRoundRectAndCusp(rectangle,_radius,linearGradientBrush,cusp,rectAlign);
///summary
///繪制指定背景的圓角矩形,并指定是否有三角小尖及其位置
////summary
///paramname="g"/param
///paramname="rectangle"矩形區(qū)域/param
///paramname="_radius"圓角半徑/param
///paramname="bgcolor"指定背景色/param
///paramname="cusp"是否有三角小尖,默認無/param
///paramname="rectAlign"三角小尖的位置,默認右上/param
publicstaticvoidDrawRoundRectAndCusp(thisGraphicsg,Rectanglerectangle,int_radius,Colorbgcolor,boolcusp=false,RectangleAlignrectAlign=RectangleAlign.RightTop)
////抗鋸齒等模式在Graphics外層自定義設(shè)置
//g.SmoothingMode=SmoothingMode.AntiAlias;
//漸變填充
varbrush=newSolidBrush(bgcolor);
g.DrawRoundRectAndCusp(rectangle,_radius,brush,cusp,rectAlign);
///summary
///繪制Brush畫刷的圓角矩形,并指定是否有三角小尖及其位置
////summary
///paramname="g"/param
///paramname="rectangle"矩形區(qū)域/param
///paramname="_radius"圓角半徑/param
///paramname="bgbrush"指定背景畫刷/param
///paramname="cusp"是否有三角小尖,默認無/param
///paramname="rectAlign"三角小尖的位置,默認右上/param
publicstaticvoidDrawRoundRectAndCusp(thisGraphicsg,Rectanglerectangle,int_radius,Brushbgbrush,boolcusp=false,RectangleAlignrectAlign=RectangleAlign.RightTop)
////抗鋸齒盡可能高質(zhì)量繪制
g.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;
g.PixelOffsetMode=PixelOffsetMode.HighQuality;
g.SmoothingMode=SmoothingMode.AntiAlias;//SmoothingMode.HighQuality
g.CompositingQuality=CompositingQuality.HighQuality;
g.InterpolationMode=InterpolationMode.HighQualityBilinear;
varrect=rectangle;
//畫尖角對應(yīng)的變更rect區(qū)域
if(cusp)
//尖角的大小默認為開始位置為_radius底邊為20,高度為13的等腰三角形
varcuspHemlineStart=_radius;
varcuspHemlineLength=20;
varcuspHeight=13;
//讓位出來的間隔暫時為尖角高度-1
varspan=cuspHeight-1;
//三角頂點
PointFp1,p2,p3;
switch(rectAlign)
caseRectangleAlign.AboveLeft:
p1=newPointF(rectangle.X+cuspHemlineStart,rectangle.Y+cuspHeight);
p2=newPointF(rectangle.X+cuspHemlineStart+cuspHemlineLength,rectangle.Y+cuspHeight);
p3=newPointF(rectangle.X+cuspHemlineStart+cuspHemlineLength/2,rectangle.Y);
rect=newRectangle(rectangle.X,rectangle.Y+span,rectangle.Width,rectangle.Height-span);
break;
caseRectangleAlign.AboveRight:
p1=newPointF(rectangle.Right-cuspHemlineStart,rectangle.Y+cuspHeight);
p2=newPointF(rectangle.Right-cuspHemlineStart-cuspHemlineLength,rectangle.Y+cuspHeight);
p3=newPointF(rectangle.Right-cuspHemlineStart-cuspHemlineLength/2,rectangle.Y);
rect=newRectangle(rectangle.X,rectangle.Y+span,rectangle.Width,rectangle.Height-span);
break;
caseRectangleAlign.RightBottom:
p1=newPointF(rectangle.Right-cuspHeight,rectangle.Bottom-cuspHemlineStart);
p2=newPointF(rectangle.Right-cuspHeight,rectangle.Bottom-cuspHemlineStart-cuspHemlineLength);
p3=newPointF(rectangle.Right,rectangle.Bottom-cuspHemlineStart-cuspHemlineLength/2);
rect=newRectangle(rectangle.X,rectangle.Y,rectangle.Width-span,rectangle.Height);
break;
caseRectangleAlign.BelowRight:
p1=newPointF(rectangle.Right-cuspHemlineStart,rectangle.Bottom-cuspHeight);
p2=newPointF(rectangle.Right-cuspHemlineStart-cuspHemlineLength,rectangle.Bottom-cuspHeight);
p3=newPointF(rectangle.Right-cuspHemlineStart-cuspHemlineLength/2,rectangle.Bottom);
rect=newRectangle(rectangle.X,rectangle.Y,rectangle.Width,rectangle.Height-span);
break;
caseRectangleAlign.BelowLeft:
p1=newPointF(rectangle.X+cuspHemlineStart,rectangle.Bottom-cuspHeight);
p2=newPointF(rectangle.X+cuspHemlineStart+cuspHemlineLength,rectangle.Bottom-cuspHeight);
p3=newPointF(rectangle.X+cuspHemlineStart+cuspHemlineLength/2,rectangle.Bottom);
rect=newRectangle(rectangle.X,rectangle.Y,rectangle.Width,rectangle.Height-span);
break;
caseRectangleAlign.LeftBottom:
p1=newPointF(rectangle.X+cuspHeight,rectangle.Bottom-cuspHemlineStart);
p2=newPointF(rectangle.X+cuspHeight,rectangle.Bottom-cuspHemlineStart-cuspHemlineLength);
p3=newPointF(rectangle.X,rectangle.Bottom-cuspHemlineStart-cuspHemlineLength/2);
rect=newRectangle(rectangle.X+span,rectangle.Y,rectangle.Width-span,rectangle.Height);
break;
caseRectangleAlign.LeftTop:
p1=newPointF(rectangle.X+cuspHeight,rectangle.Y+cuspHemlineStart);
p2=newPointF(rectangle.X+cuspHeight,rectangle.Y+cuspHemlineStart+cuspHemlineLength);
p3=newPointF(rectangle.X,rectangle.Y+cuspHemlineStart+cuspHemlineLength/2);
rect=newRectangle(rectangle.X+span,rectangle.Y,rectangle.Width-span,rectangle.Height);
break;
caseRectangleAlign.RightTop:
default:
p1=newPointF(rectangle.Right-cuspHeight,rectangle.Y+cuspHemlineStart);
p2=newPointF(rectangle.Right-cuspHeight,rectangle.Y+cuspHemlineStart+cuspHemlineLength);
p3=newPointF(rectangle.Right,rectangle.Y+cuspHemlineStart+cuspHemlineLength/2);
rect=newRectangle(rectangle.X,rectangle.Y,rectangle.Width-span,rectangle.Height);
break;
PointF[]ptsArray=newPointF[]{p1,p2,p3};
//填充參數(shù)點所指定的多邊形內(nèi)部
g.FillPolygon(bgbrush,ptsArray);
//填充
g.FillPath(bgbrush,rect.GetRoundedRectPath(_radius));
///summary
///根據(jù)普通矩形得到圓角矩形的路徑【根據(jù)矩形區(qū)域rect,計算呈現(xiàn)radius圓角的Graphics路徑】
////summary
///paramname="rect"原始矩形/param
///paramname="radius"半徑/param
///returns圖形路徑/returns
publicstaticGraphicsPathGetRoundedRectPath(thisRectanglerect,intradius)
#region正確繪制圓角矩形區(qū)域
intR=radius*2;
RectanglearcRect=newRectangle(rect.Location,newSize(R,R));
GraphicsPathpath=newGraphicsPath();
if(radius=0)
path.AddRectangle(rect);
else
//左上圓弧左手坐標系,順時針為正從180開始,轉(zhuǎn)90度
path.AddArc(arcRect,180,90);
//右上圓弧
arcRect.X=rect.Right-R;
path.AddArc(arcRect,270,90);
//右下圓弧
arcRect.Y=rect.Bottom-R;
path.AddArc(arcRect,0,90);
//左下圓弧
arcRect.X=rect.Left;
path.AddArc(arcRect,90,90);
//path.CloseFigure();
//閉合路徑中所有開放圖形,并形成新圖形
path.CloseAllFigures();
returnpath;
#endregion
///summary
///獲取圓角矩形的路徑
////summary
///paramname="rect"原始矩形/param
///paramname="radius"半徑/param
///returns圖形路徑/returns
publicstaticGraphicsPathGetRoundedRectPath(intx,inty,intwidth,intheight,intradius)
Rectanglerect=newRectangle(x,y,width,height);
returnrect.GetRoundedRectPath(radius);
}
測試尖角的顯示位置
復(fù)制幾個Panel,在Paint事件中分別處理尖角的位置
panel1.Paint+=Panel1_Paint;
panel3.Paint+=Panel1_Paint;
panel4.Paint+=Panel1_Paint;
panel5.Paint+=Panel1_Paint;
panel6.Paint+=Panel1_Paint;
panel7.Paint+=Panel1_Paint;
panel8.Paint+=Panel1_Paint;
panel9.Paint+=Panel1_Paint;
///......
privatevoidPanel1_Paint(objectsender,PaintEventArgse)
varpanel=senderasPanel;
varrectAlign=RectangleAlign.RightTop;
switch(panel.Name)
case"panel3":
rectAlign=RectangleAlign.AboveLeft;
break;
case"panel4":
rectAlign=RectangleAlign.AboveRight;
break;
case"panel5":
rectAlign=RectangleAlign.BelowLeft;
break;
case"panel6":
rectAlign=RectangleAlign.BelowRight;
break;
case"panel7":
rectAlign=RectangleAlign.LeftBottom;
break;
case"panel8":
rectAlign=RectangleAlign.LeftTop;
break;
case"panel9":
rectAlign=RectangleAlign.RightBottom;
break;
default:
break;
varrect=e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,panel.Width,panel.Height),18,Color.FromArgb(90,143,0),Color.FromArgb(41,67,0),true,rectAlign);
e.Graphics.DrawText(rect,"這是一個Panel控件,非常適合顯示消息",Color.White,panel.Font);
}
查看效果:
重繪控件后文本的處理
由于重新繪制導(dǎo)致文本也被覆蓋的情況,有比較常見的兩種處理方法:
重繪控件的同時,重繪文本文字通過添加Label控件實現(xiàn)文本處理
同時重繪文本
同樣將繪制文本的方法提取為擴展方法,借助StringFormat字符串格式對象實現(xiàn)文字的布局處理。
不推薦使用Graphics.DrawString繪制按鈕控件(Rectangle區(qū)域)內(nèi)的文字,當然DrawString也有一定有時比如文字方向的處理。
///summary
///繪制(控件區(qū)域)文本內(nèi)容
////summary
///paramname="g"/param
///paramname="rect"/param
///paramname="text"/param
///paramname="color"/param
///paramname="font"/param
///paramname="_textAlign"文字布局,默認居中。實際測試并未真正的居中,垂直方向偏上,改為通過計算rect的中心位置實現(xiàn),使用微軟雅黑還好點,字體大小最好偶數(shù)/param
///paramname="rtl"是否RightToLeft無效果,不推薦使用/param
publicstaticvoidDrawText(thisGraphicsg,Rectanglerect,stringtext,Colorcolor,Fontfont,ContentAlignment_textAlign=ContentAlignment.MiddleCenter,boolrtl=false)
varformatFlags=TextFormatFlags.HorizontalCenter|TextFormatFlags.VerticalCenter;//默認居中
switch(_textAlign)
caseContentAlignment.TopLeft:
formatFlags=TextFormatFlags.Top|TextFormatFlags.Left;
break;
caseContentAlignment.TopCenter:
formatFlags=TextFormatFlags.Top|TextFormatFlags.HorizontalCenter;
break;
caseContentAlignment.TopRight:
formatFlags=TextFormatFlags.Top|TextFormatFlags.Right;
break;
caseContentAlignment.MiddleLeft:
formatFlags=TextFormatFlags.VerticalCenter|TextFormatFlags.Left;
break;
caseContentAlignment.MiddleRight:
formatFlags=TextFormatFlags.VerticalCenter|TextFormatFlags.Right;
break;
caseContentAlignment.BottomLeft:
formatFlags=TextFormatFlags.Bottom|TextFormatFlags.Left;
break;
caseContentAlignment.BottomCenter:
formatFlags=TextFormatFlags.Bottom|TextFormatFlags.HorizontalCenter;
break;
caseContentAlignment.BottomRight:
formatFlags=TextFormatFlags.Bottom|TextFormatFlags.Right;
break;
caseContentAlignment.MiddleCenter:
default:
break;
if(rtl)
formatFlags|=TextFormatFlags.RightToLeft;//無效果
TextRenderer.DrawText(g,text,font,rect,color,formatFlags);
}
要注意添加了小三角后的文字繪制區(qū)域問題,如果使用默認的全部預(yù)期有可能導(dǎo)致文字超出范圍,且,布局也不是相對于繪制的主體。如下圖對比的效果。
因此,可修改圓角繪制的函數(shù),使其返回繪制后的主體區(qū)域。
privatevoidPanel1_Paint(objectsender,PaintEventArgse)
varpanel=senderasPanel;
varrect=e.Graphics.DrawRoundRectAndCusp(newRectangle(0,0,panel.Width,panel.Height),18,Color.FromArgb(90,143,0),Color.FromArgb(41,67,0),true,rectAlign);
//e.Graphics.DrawText(e.ClipRectangle,"這是一個Panel控件,非常適合顯示消息",Color.White,panel.Font);
//使用合適的區(qū)域
e.Graphics.DrawText(rect,"這是一個Panel控件,非常適合顯示消息",Color.White,panel.Font);
}
通過添加Label控件實現(xiàn)對文本的處理【有尖角時需要額外處理】
label2.Text="我是Label顯示在圓角按鈕上";
label2.Parent=button1;
label2.AutoSize=false;
label2.Dock=DockStyle.Fill;
label2.BackColor=Color.Transparent;
label2.TextAlign=ContentAlignment.MiddleCenter;
label2.ForeColor=Color.Wheat;
Paint事件中繪制圓角的優(yōu)點
完全由用戶繪制按鈕區(qū)域?qū)崿F(xiàn)圓角【之前文章介紹過】,可以發(fā)現(xiàn),與直接在Paint事件中實現(xiàn)圓角,有著一定的鋸齒,雖然不是很嚴重,但是還是Paint事件中實現(xiàn)的圓角看著相對好一些。
之前完全由用戶繪制
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 拆除工程環(huán)境補償協(xié)議書
- 5G技術(shù)對物聯(lián)網(wǎng)集成的影響-洞察闡釋
- 大型活動彩鋼房拆除與應(yīng)急救援協(xié)議
- 研發(fā)型廠區(qū)租賃合同及知識產(chǎn)權(quán)共享協(xié)議
- 多式聯(lián)運成本動態(tài)監(jiān)控-洞察闡釋
- 藝術(shù)服務(wù)的智能化改造-洞察闡釋
- 物業(yè)管理智慧化與成本控制研究-洞察闡釋
- 便利店品牌加盟協(xié)議范文
- 生物醫(yī)學(xué)中混合系統(tǒng)建模與仿真應(yīng)用-洞察闡釋
- 數(shù)字化轉(zhuǎn)型背景下的環(huán)保設(shè)備智能制造模式創(chuàng)新-洞察闡釋
- 2024年度押運服務(wù)收費標準及協(xié)議范本3篇
- GB/T 44948-2024鋼質(zhì)模鍛件金屬流線取樣要求及評定
- 腹壁纖維肉瘤病因介紹
- 少數(shù)民族民歌+蒙古民族歌曲-【知識精研】高中音樂人音版(2019)必修+音樂鑒賞
- 《小學(xué)教師專業(yè)發(fā)展》課程教學(xué)大綱
- 教育部《中小學(xué)校園食品安全和膳食經(jīng)費管理工作指引》知識專題講座
- 有限空間監(jiān)理實施細則
- 把信送給加西亞 (完整版)
- 中藥治療口腔潰瘍
- 色卡-CBCC中國建筑標準色卡(千色卡1026色)
- 《數(shù)據(jù)資產(chǎn)會計》 課件 第二章 數(shù)據(jù)的資產(chǎn)化
評論
0/150
提交評論