C#用戶控件之溫度計設計
本文以一個用戶控件【UserControl】實現溫度計的小例子,簡述用戶控件的相關知識,以供學習分享使用,如有不足之處,還請指正。
概述
一般而言,用戶控件【UserControl】,是在VisualStudio提供的默認控件不能滿足實際的工作需要,才需要在現有控件的基礎之上進行新的擴展,來實現自己的功能。用戶控件有自己特有的屬性,事件,方法來支撐特定的功能。用戶控件封裝實現的細節,可以進行方便的複用。
用戶控件分類
用戶控件主要有以下三種分類,本例採用的是第三種。
複合控件(CompositeControls):將現有的各種控件組合起來,形成一個新的控件,來滿足用戶的需求。
擴展控件(ExtendedControls):就是在現有的控件基礎上,派生出一個新的控件,增加新的功能,或者修改原有功能,來滿足用戶需求。
自定義控件(CustomControls):就是直接從UserControl類派生,也就是說完全由自己來設計、實現一個全新的控件,這是最靈活、最強大的方法。
涉及知識點
本例中主要涉及以下知識點:
UserControl:提供一個可用來創建其他控件的空控件。用戶創建一個用戶控件,會默認繼承這個類。
OnPaint:控件重繪方法,是protected修飾符,本例中需要重寫此方法。
Graphics:密封類,不可被繼承,用於繪製圖形(包括矩形,扇形,直線等)。
ToolTip:表示一個長方形的小彈出窗口,該窗口在用戶將指針懸停在一個控件上時顯示有關該控件用途的簡短說明。
鼠標事件函數:OnMouseHover鼠標懸停時觸發函數,OnMouseLeave鼠標離開時觸發函數。
DataGridView:在可自定義的網格中顯示數據。
示例效果圖
本例中示例效果圖如下所示:
關鍵代碼
本例中的關鍵代碼如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Drawing;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
namespaceDemoThermometer
{
publicpartialclassThermometer:UserControl
{
#region屬性與構造函數
privateintinterval=10;
///<summary>
///刻度間隔
///</summary>
publicintInterval
{
get{returninterval;}
set{interval=value;}
}
privateintminValue=-50;
///<summary>
///最低溫度
///</summary>
publicintMinValue
{
get{returnminValue;}
set{minValue=value;}
}
privateintmaxValue=50;
///<summary>
///最高溫度
///</summary>
publicintMaxValue
{
get{returnmaxValue;}
set{maxValue=value;}
}
privatefloatcurValue=0;
///<summary>
///當前溫度
///</summary>
publicfloatCurValue
{
get{returncurValue;}
set{curValue=value;}
}
privateColorthermoColor=Color.Red;
///<summary>
///溫度條顏色
///</summary>
publicColorThermoColor
{
get{returnthermoColor;}
set{thermoColor=value;}
}
privateColorbackGroundColor=Color.SkyBlue;
///<summary>
///溫度計背景色
///</summary>
publicColorBackGroundColor
{
get{returnbackGroundColor;}
set{backGroundColor=value;}
}
privateFontthermoFont=newFont("宋體",10,FontStyle.Regular);
///<summary>
///溫度計上字體
///</summary>
publicFontThermoFont
{
get{returnthermoFont;}
set{thermoFont=value;}
}
privatestringthermoTitle="溫度計";
///<summary>
///標題
///</summary>
publicstringThermoTitle
{
get{returnthis.thermoTitle;}
set{this.thermoTitle=value;}
}
privateboolshowTip=false;
///<summary>
///是否顯示提示
///</summary>
publicboolShowTip
{
get{returnshowTip;}
set{showTip=value;}
}
privateToolTiptip=newToolTip();
publicThermometer()
{
InitializeComponent();
}
#endregion
protectedoverridevoidOnPaint(PaintEventArgse)
{
//base.OnPaint(e);
//this.BackColor=this.backGroundColor;
intwidth=this.Width;
intheight=this.Height-50;
Graphicsg=e.Graphics;
intc_x=width/2;
intc_y=height/2;
intpadding=this.Padding.All;//空白
intr=(width-2*padding)/2;//半徑
intd=2*r;//直徑
intdis=2;//兩個半圓之間的間隔
intdis2=2*dis;//填充與邊框之間的距離
intstartAngle1=-180;
intstartAngle2=0;
intsweepAngle1=180;
//首先畫頂端一個半圓
g.DrawPie(Pens.Black,newRectangle(padding,padding,d,d),startAngle1,sweepAngle1);
g.DrawPie(Pens.Black,newRectangle(padding+dis,padding+dis,d-2*dis,d-2*dis),startAngle1,sweepAngle1);
//填充背景色
g.FillPie(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,padding+dis2,d-2*dis2,d-2*dis2),startAngle1,sweepAngle1);
//畫底端一個半圓
g.DrawPie(Pens.Black,newRectangle(padding,height-d-padding,d,d),startAngle2,sweepAngle1);
g.DrawPie(Pens.Black,newRectangle(padding+dis,height-d-padding+dis,d-2*dis,d-2*dis),startAngle2,sweepAngle1);
g.FillPie(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,height-d-padding+dis2,d-2*dis2,d-2*dis2),startAngle2,sweepAngle1);
//畫一個矩形
g.DrawRectangle(Pens.Black,newRectangle(padding,padding+r,d,height-d-2*padding));
g.DrawRectangle(Pens.Black,newRectangle(padding+dis,padding+r+dis,d-2*dis,height-d-2*padding-2*dis));
//背景色填充,去掉邊界線
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+3,padding+r-2,2*r-6,6));
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+3,height-r-padding-4,2*r-6,8));
//背景色填充中間部分
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,padding+r+dis2,d-2*dis2,height-d-2*padding-2*dis2));
//畫刻度
ints_s_x_1=padding+r-20;
ints_s_x_2=width-padding-r+20;
ints_s_y=padding+r+4;
inttotal=this.maxValue-this.minValue;
intscale_width=5;//刻度寬度
intscale=total/this.interval;
intpscale=(height-2*r-2*padding)/this.interval;//像素間隔
//豎線
g.DrawLine(Pens.Black,newPoint(s_s_x_1,s_s_y),newPoint(s_s_x_1,s_s_y+this.interval*pscale));
g.DrawLine(Pens.Black,newPoint(s_s_x_2,s_s_y),newPoint(s_s_x_2,s_s_y+this.interval*pscale));
for(inti=0;i<=this.interval;i++){
//橫線刻度
g.DrawLine(Pens.Black,newPoint(s_s_x_1-scale_width,s_s_y+i*pscale),newPoint(s_s_x_1,s_s_y+i*pscale));
g.DrawLine(Pens.Black,newPoint(s_s_x_2,s_s_y+i*pscale),newPoint(s_s_x_2+scale_width,s_s_y+i*pscale));
//畫刻度數字
g.DrawString((this.maxValue-(scale*i)).ToString(),this.thermoFont,newSolidBrush(this.ForeColor),newPoint(s_s_x_1-35,s_s_y+i*pscale-10));
g.DrawString((this.maxValue-(scale*i)).ToString(),this.thermoFont,newSolidBrush(this.ForeColor),newPoint(s_s_x_2+10,s_s_y+i*pscale-10));
}
intwhite_width=3;//中間白色線寬度
//畫條白色細線
g.FillRectangle(Brushes.White,newRectangle(c_x-white_width,r/2,white_width*2,height-r));
//在底部畫一個圓球
g.FillPie(newSolidBrush(this.thermoColor),newRectangle(c_x-r/2+5,height-r-padding,r-10,r-10),0,360);
//根據當前溫度畫紅色線
intred_width=5;//紅色溫度線寬度
floatii=(this.curValue-this.minValue)/this.interval;
g.FillRectangle(newSolidBrush(this.thermoColor),newRectangleF(c_x-red_width,height-r-padding-(ii*pscale)-4,2*red_width,ii*pscale+5));//此處有一像素的誤差
//畫標誌字符單℃位
g.DrawString("℃",this.thermoFont,newSolidBrush(this.ForeColor),newPoint(c_x-30,r/2-10));
FonttitleFont=newFont("宋體",13,FontStyle.Bold);
//繪製標題
SizeFtsize=g.MeasureString(this.thermoTitle,titleFont);
g.DrawString(this.thermoTitle,titleFont,newSolidBrush(this.ForeColor),newPointF(c_x-(tsize.Width/2),height+5));
stringcur=string.Format("當前溫度:{0}℃",this.curValue);
SizeFtsize2=g.MeasureString(cur,this.thermoFont);
g.DrawString(cur,this.thermoFont,newSolidBrush(this.thermoColor),newPointF(c_x-(tsize2.Width/2),height+10+tsize.Height));
}
///<summary>
///當鼠標覆蓋進去時
///</summary>
///<paramname="e"></param>
protectedoverridevoidOnMouseHover(EventArgse)
{
this.showTip=true;
//需要顯示的內容
intx=this.Width/2;
inty=(this.Height-50)/2;
StringBuildersbTips=newStringBuilder();
//sbTips.AppendLine(this.ThermoTitle);
sbTips.AppendLine(string.Format("當前溫度:{0}",this.curValue));
sbTips.AppendLine("單位:℃");
tip.ToolTipTitle=this.ThermoTitle;
tip.IsBalloon=true;
tip.UseFading=true;
//t.SetToolTip(this,sbTips.ToString());
tip.Show(sbTips.ToString(),this,x,y);
}
protectedoverridevoidOnMouseLeave(EventArgse)
{
this.showTip=false;
tip.Hide(this);
}
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
概述
一般而言,用戶控件【UserControl】,是在VisualStudio提供的默認控件不能滿足實際的工作需要,才需要在現有控件的基礎之上進行新的擴展,來實現自己的功能。用戶控件有自己特有的屬性,事件,方法來支撐特定的功能。用戶控件封裝實現的細節,可以進行方便的複用。
用戶控件分類
用戶控件主要有以下三種分類,本例採用的是第三種。
複合控件(CompositeControls):將現有的各種控件組合起來,形成一個新的控件,來滿足用戶的需求。
擴展控件(ExtendedControls):就是在現有的控件基礎上,派生出一個新的控件,增加新的功能,或者修改原有功能,來滿足用戶需求。
自定義控件(CustomControls):就是直接從UserControl類派生,也就是說完全由自己來設計、實現一個全新的控件,這是最靈活、最強大的方法。
涉及知識點
本例中主要涉及以下知識點:
UserControl:提供一個可用來創建其他控件的空控件。用戶創建一個用戶控件,會默認繼承這個類。
OnPaint:控件重繪方法,是protected修飾符,本例中需要重寫此方法。
Graphics:密封類,不可被繼承,用於繪製圖形(包括矩形,扇形,直線等)。
ToolTip:表示一個長方形的小彈出窗口,該窗口在用戶將指針懸停在一個控件上時顯示有關該控件用途的簡短說明。
鼠標事件函數:OnMouseHover鼠標懸停時觸發函數,OnMouseLeave鼠標離開時觸發函數。
DataGridView:在可自定義的網格中顯示數據。
示例效果圖
本例中示例效果圖如下所示:
關鍵代碼
本例中的關鍵代碼如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Drawing;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows.Forms;
namespaceDemoThermometer
{
publicpartialclassThermometer:UserControl
{
#region屬性與構造函數
privateintinterval=10;
///<summary>
///刻度間隔
///</summary>
publicintInterval
{
get{returninterval;}
set{interval=value;}
}
privateintminValue=-50;
///<summary>
///最低溫度
///</summary>
publicintMinValue
{
get{returnminValue;}
set{minValue=value;}
}
privateintmaxValue=50;
///<summary>
///最高溫度
///</summary>
publicintMaxValue
{
get{returnmaxValue;}
set{maxValue=value;}
}
privatefloatcurValue=0;
///<summary>
///當前溫度
///</summary>
publicfloatCurValue
{
get{returncurValue;}
set{curValue=value;}
}
privateColorthermoColor=Color.Red;
///<summary>
///溫度條顏色
///</summary>
publicColorThermoColor
{
get{returnthermoColor;}
set{thermoColor=value;}
}
privateColorbackGroundColor=Color.SkyBlue;
///<summary>
///溫度計背景色
///</summary>
publicColorBackGroundColor
{
get{returnbackGroundColor;}
set{backGroundColor=value;}
}
privateFontthermoFont=newFont("宋體",10,FontStyle.Regular);
///<summary>
///溫度計上字體
///</summary>
publicFontThermoFont
{
get{returnthermoFont;}
set{thermoFont=value;}
}
privatestringthermoTitle="溫度計";
///<summary>
///標題
///</summary>
publicstringThermoTitle
{
get{returnthis.thermoTitle;}
set{this.thermoTitle=value;}
}
privateboolshowTip=false;
///<summary>
///是否顯示提示
///</summary>
publicboolShowTip
{
get{returnshowTip;}
set{showTip=value;}
}
privateToolTiptip=newToolTip();
publicThermometer()
{
InitializeComponent();
}
#endregion
protectedoverridevoidOnPaint(PaintEventArgse)
{
//base.OnPaint(e);
//this.BackColor=this.backGroundColor;
intwidth=this.Width;
intheight=this.Height-50;
Graphicsg=e.Graphics;
intc_x=width/2;
intc_y=height/2;
intpadding=this.Padding.All;//空白
intr=(width-2*padding)/2;//半徑
intd=2*r;//直徑
intdis=2;//兩個半圓之間的間隔
intdis2=2*dis;//填充與邊框之間的距離
intstartAngle1=-180;
intstartAngle2=0;
intsweepAngle1=180;
//首先畫頂端一個半圓
g.DrawPie(Pens.Black,newRectangle(padding,padding,d,d),startAngle1,sweepAngle1);
g.DrawPie(Pens.Black,newRectangle(padding+dis,padding+dis,d-2*dis,d-2*dis),startAngle1,sweepAngle1);
//填充背景色
g.FillPie(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,padding+dis2,d-2*dis2,d-2*dis2),startAngle1,sweepAngle1);
//畫底端一個半圓
g.DrawPie(Pens.Black,newRectangle(padding,height-d-padding,d,d),startAngle2,sweepAngle1);
g.DrawPie(Pens.Black,newRectangle(padding+dis,height-d-padding+dis,d-2*dis,d-2*dis),startAngle2,sweepAngle1);
g.FillPie(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,height-d-padding+dis2,d-2*dis2,d-2*dis2),startAngle2,sweepAngle1);
//畫一個矩形
g.DrawRectangle(Pens.Black,newRectangle(padding,padding+r,d,height-d-2*padding));
g.DrawRectangle(Pens.Black,newRectangle(padding+dis,padding+r+dis,d-2*dis,height-d-2*padding-2*dis));
//背景色填充,去掉邊界線
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+3,padding+r-2,2*r-6,6));
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+3,height-r-padding-4,2*r-6,8));
//背景色填充中間部分
g.FillRectangle(newSolidBrush(this.backGroundColor),newRectangle(padding+dis2,padding+r+dis2,d-2*dis2,height-d-2*padding-2*dis2));
//畫刻度
ints_s_x_1=padding+r-20;
ints_s_x_2=width-padding-r+20;
ints_s_y=padding+r+4;
inttotal=this.maxValue-this.minValue;
intscale_width=5;//刻度寬度
intscale=total/this.interval;
intpscale=(height-2*r-2*padding)/this.interval;//像素間隔
//豎線
g.DrawLine(Pens.Black,newPoint(s_s_x_1,s_s_y),newPoint(s_s_x_1,s_s_y+this.interval*pscale));
g.DrawLine(Pens.Black,newPoint(s_s_x_2,s_s_y),newPoint(s_s_x_2,s_s_y+this.interval*pscale));
for(inti=0;i<=this.interval;i++){
//橫線刻度
g.DrawLine(Pens.Black,newPoint(s_s_x_1-scale_width,s_s_y+i*pscale),newPoint(s_s_x_1,s_s_y+i*pscale));
g.DrawLine(Pens.Black,newPoint(s_s_x_2,s_s_y+i*pscale),newPoint(s_s_x_2+scale_width,s_s_y+i*pscale));
//畫刻度數字
g.DrawString((this.maxValue-(scale*i)).ToString(),this.thermoFont,newSolidBrush(this.ForeColor),newPoint(s_s_x_1-35,s_s_y+i*pscale-10));
g.DrawString((this.maxValue-(scale*i)).ToString(),this.thermoFont,newSolidBrush(this.ForeColor),newPoint(s_s_x_2+10,s_s_y+i*pscale-10));
}
intwhite_width=3;//中間白色線寬度
//畫條白色細線
g.FillRectangle(Brushes.White,newRectangle(c_x-white_width,r/2,white_width*2,height-r));
//在底部畫一個圓球
g.FillPie(newSolidBrush(this.thermoColor),newRectangle(c_x-r/2+5,height-r-padding,r-10,r-10),0,360);
//根據當前溫度畫紅色線
intred_width=5;//紅色溫度線寬度
floatii=(this.curValue-this.minValue)/this.interval;
g.FillRectangle(newSolidBrush(this.thermoColor),newRectangleF(c_x-red_width,height-r-padding-(ii*pscale)-4,2*red_width,ii*pscale+5));//此處有一像素的誤差
//畫標誌字符單℃位
g.DrawString("℃",this.thermoFont,newSolidBrush(this.ForeColor),newPoint(c_x-30,r/2-10));
FonttitleFont=newFont("宋體",13,FontStyle.Bold);
//繪製標題
SizeFtsize=g.MeasureString(this.thermoTitle,titleFont);
g.DrawString(this.thermoTitle,titleFont,newSolidBrush(this.ForeColor),newPointF(c_x-(tsize.Width/2),height+5));
stringcur=string.Format("當前溫度:{0}℃",this.curValue);
SizeFtsize2=g.MeasureString(cur,this.thermoFont);
g.DrawString(cur,this.thermoFont,newSolidBrush(this.thermoColor),newPointF(c_x-(tsize2.Width/2),height+10+tsize.Height));
}
///<summary>
///當鼠標覆蓋進去時
///</summary>
///<paramname="e"></param>
protectedoverridevoidOnMouseHover(EventArgse)
{
this.showTip=true;
//需要顯示的內容
intx=this.Width/2;
inty=(this.Height-50)/2;
StringBuildersbTips=newStringBuilder();
//sbTips.AppendLine(this.ThermoTitle);
sbTips.AppendLine(string.Format("當前溫度:{0}",this.curValue));
sbTips.AppendLine("單位:℃");
tip.ToolTipTitle=this.ThermoTitle;
tip.IsBalloon=true;
tip.UseFading=true;
//t.SetToolTip(this,sbTips.ToString());
tip.Show(sbTips.ToString(),this,x,y);
}
protectedoverridevoidOnMouseLeave(EventArgse)
{
this.showTip=false;
tip.Hide(this);
}
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.