Winform控件優(yōu)化之圓角按鈕1_第1頁
Winform控件優(yōu)化之圓角按鈕1_第2頁
Winform控件優(yōu)化之圓角按鈕1_第3頁
Winform控件優(yōu)化之圓角按鈕1_第4頁
Winform控件優(yōu)化之圓角按鈕1_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第Winform控件優(yōu)化之圓角按鈕1//盡可能高質(zhì)量繪制

e.Graphics.TextRenderingHint=System.Drawing.Text.TextRenderingHint.AntiAlias;

e.Graphics.PixelOffsetMode=PixelOffsetMode.HighQuality;

e.Graphics.SmoothingMode=SmoothingMode.AntiAlias;

e.Graphics.CompositingQuality=CompositingQuality.HighQuality;

e.Graphics.InterpolationMode=InterpolationMode.HighQualityBilinear;

Rectanglerect=newRectangle(0,0,this.Width,this.Height);

varpath=GetRoundedRectPath(rect,radius);

this.Region=newRegion(path);

ColorbaseColor;

//ColorborderColor;

//ColorinnerBorderColor=this._baseColor;//Color.FromArgb(200,255,255,255);;

switch(ControlState)

caseControlState.Hover:

baseColor=this._hoverColor;

break;

caseControlState.Pressed:

baseColor=this._pressedColor;

break;

caseControlState.Normal:

baseColor=this._normalColor;

break;

default:

baseColor=this._normalColor;

break;

using(SolidBrushb=newSolidBrush(baseColor))

e.Graphics.FillPath(b,path);//填充路徑,而不是DrawPath

using(Brushbrush=newSolidBrush(this.ForeColor))

//文本布局對象

using(StringFormatgs=newStringFormat())

//文字布局

switch(_textAlign)

caseContentAlignment.TopLeft:

gs.Alignment=StringAlignment.Near;

gs.LineAlignment=StringAlignment.Near;

break;

caseContentAlignment.TopCenter:

gs.Alignment=StringAlignment.Center;

gs.LineAlignment=StringAlignment.Near;

break;

caseContentAlignment.TopRight:

gs.Alignment=StringAlignment.Far;

gs.LineAlignment=StringAlignment.Near;

break;

caseContentAlignment.MiddleLeft:

gs.Alignment=StringAlignment.Near;

gs.LineAlignment=StringAlignment.Center;

break;

caseContentAlignment.MiddleCenter:

gs.Alignment=StringAlignment.Center;//居中

gs.LineAlignment=StringAlignment.Center;//垂直居中

break;

caseContentAlignment.MiddleRight:

gs.Alignment=StringAlignment.Far;

gs.LineAlignment=StringAlignment.Center;

break;

caseContentAlignment.BottomLeft:

gs.Alignment=StringAlignment.Near;

gs.LineAlignment=StringAlignment.Far;

break;

caseContentAlignment.BottomCenter:

gs.Alignment=StringAlignment.Center;

gs.LineAlignment=StringAlignment.Far;

break;

caseContentAlignment.BottomRight:

gs.Alignment=StringAlignment.Far;

gs.LineAlignment=StringAlignment.Far;

break;

default:

gs.Alignment=StringAlignment.Center;//居中

gs.LineAlignment=StringAlignment.Center;//垂直居中

break;

//if(this.RightToLeft==RightToLeft.Yes)

//{

//gs.FormatFlags=StringFormatFlags.DirectionRightToLeft;

//}

e.Graphics.DrawString(this.Text,this.Font,brush,rect,gs);

///summary

///根據(jù)矩形區(qū)域rect,計(jì)算呈現(xiàn)radius圓角的Graphics路徑

////summary

///paramname="rect"/param

///paramname="radius"/param

///returns/returns

privateGraphicsPathGetRoundedRectPath(Rectanglerect,intradius)

#region正確繪制圓角矩形區(qū)域

intR=radius*2;

RectanglearcRect=newRectangle(rect.Location,newSize(R,R));

GraphicsPathpath=newGraphicsPath();

//左上圓弧左手坐標(biāo)系,順時(shí)針為正從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();

returnpath;

#endregion

protectedoverridevoidOnSizeChanged(EventArgse)

base.OnSizeChanged(e);

}

參考C#Winform實(shí)現(xiàn)圓角無鋸齒按鈕

可以改進(jìn)和實(shí)現(xiàn)的

添加Border,實(shí)現(xiàn)Border顏色和寬度的指定(目前的一個(gè)思路時(shí)利用路徑在外層填充一個(gè)圓角矩形,在內(nèi)層再填充一個(gè)圓角矩形,形成有Border的效果;另一個(gè)思路時(shí),畫路徑時(shí),繪制內(nèi)層路徑和圓環(huán)路徑,Border部分是一個(gè)圓角的圓環(huán)路徑,而后分別填充顏色;還有就是繪制路徑線條,線條作為Border。)通過百分比實(shí)現(xiàn)圓角完全擴(kuò)展Button,通過標(biāo)志位啟動圓角和修改圓角,做到圓角和普通Button共存。修改使用RectangleF對象,使用浮點(diǎn)數(shù)繪制矩形和路徑圓角半徑radius指定為0的處理

Rectangle.Round(RectangleF)將RectangleF對象轉(zhuǎn)換為Rectangle,通過舍入最近的數(shù)。

利用填充內(nèi)外兩層圓角矩形路徑形成Border

【有著致命缺陷(隨后介紹了正確處理的方案)】

控件的Region區(qū)域一定指定,并且要包含全部的Graphics繪制的內(nèi)容,否則顯示不全,包含在Region內(nèi)才能全部顯示出來。

Region區(qū)域指定的是控件的區(qū)域,表示的是控件的范圍

如下,通過Border大小_borderWidth計(jì)算不同的路徑,指定Region。

矩形區(qū)域長寬不同,無法按照等比的方式計(jì)算長寬方向上固定邊框?qū)挾鹊谋壤?;因此,?nèi)部的內(nèi)層圓角半徑也無法準(zhǔn)確計(jì)算,理論采用比例較小的比較合適

//外層圓角矩形

RectangleoutRect=newRectangle(0,0,this.Width,this.Height);

varoutPath=outRect.GetRoundedRectPath(_radius);

//計(jì)算內(nèi)存圓角矩形,不嚴(yán)謹(jǐn)

Rectanglerect=newRectangle(_borderWidth,_borderWidth,this.Width-_borderWidth*2,this.Height-_borderWidth*2);

varpath=rect.GetRoundedRectPath(_radius);

//this.Region=newRegion(path);

//必須正確指定外層路徑outPath的全部區(qū)域,否則無法顯示完全填充的全部

this.Region=newRegion(outPath);

然后分別填充兩個(gè)路徑:

using(SolidBrushborderB=newSolidBrush(_borderColor))

e.Graphics.FillPath(borderB,outPath);

using(SolidBrushb=newSolidBrush(baseColor))

e.Graphics.FillPath(b,path);//填充路徑,而不是DrawPath

}

通過縮放實(shí)現(xiàn)正確的內(nèi)外兩層圓角矩形路徑

通過縮放實(shí)現(xiàn)正確Border的原理主要如下圖所示,長寬縮小BorderSize大小,圓角半徑同樣縮小BorderSize,兩個(gè)內(nèi)外層圓角矩形的圓角在共同半徑下繪制圓角弧線。

Rectangle.Inflate()方法用于返回Rectangle結(jié)構(gòu)的放大副本,第二三個(gè)參數(shù)表示x、y方向放大或縮小的量。

varinnerRect=Rectangle.Inflate(outRect,-borderSize,-borderSize);

則對應(yīng)得到內(nèi)層圓角路徑為:

GraphicsPathinnerPath=innerRect.GetRoundedRectPath(borderRadius-borderSize)

從這里可以看出,需要保證borderSize小于borderRadius。

CDI+路徑的填充模式

GraphicsPath的填充模式FillMode默認(rèn)是FillMode.Alternate,所以替代填充可以實(shí)現(xiàn)內(nèi)外兩層的填充實(shí)現(xiàn)Border效果。

填充模式另一個(gè)選項(xiàng)為FillMode.Winding,可實(shí)現(xiàn)環(huán)繞效果,它們都是應(yīng)用在路徑發(fā)生重疊(overlap)時(shí),不同的填充效果??删唧w測試不同效果

GraphicsPathgp=newGraphicsPath(FillMode.Winding);

直接繪制路徑作為邊框【推薦】**

通過DrawPath直接繪制邊框,注意寬度的處理。

//繪制邊框

using(Penpen=newPen(_borderColor,_borderWidth*2))

e.Graphics.DrawPath(pen,path);

//繪制路徑上,會有一半位于路徑外層,即Region外面,無法顯示出來。因此設(shè)置為雙borderWidth

}

記得同時(shí)修改下文字繪制的區(qū)域范圍問題,邊框?qū)挾日紦?jù)了區(qū)域的一部分。否則,在空間很小時(shí),文字會位于邊框上。

查看效果如下:

最好的處理不要使用_borderWidth*2,而是使用原本大小,繪制的Path縮小在半個(gè)_borderWith范圍內(nèi)。比如:newRectangle(rect.X+_borderWidth/2,rect.Y+_borderWidth/2,rect.

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論