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);


  }


  }


  }


  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值