0.选择基类

  1. public class MySlider : Control

1.设置控件的Style

  在构造函数里添加:

  1. public MySlider()
  2. {
  3. //1.设置控件Style
  4. this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
  5.  
  6. //9.1
  7. }

2.定义变量,并对一些变量进行一些默认设置

  1. //2.定义变量,并对一些变量进行一些默认设置
  2. Rectangle foreRect;
  3. Rectangle backRect;
  4. Rectangle setRect;
  5.  
  6. Color backgroundColor = Color.White;//背景色
  7. Color foregroundColor = Color.Gray;//已加载颜色
  8. Color setRectColor = Color.Black;//控制块
  9. Color fontColor = Color.Black;//字体颜色
  10.  
  11. int maximum = ; //进度条的最大值
  12. int minimum = ; //进度条的最小值
  13. double myValue = ;//当前进度值
  14.  
  15. bool showPercent; //显示当前的百分比
  16. float fontSize = ;//控件字体的大小
  17. FontFamily myFontFamily = new FontFamily("宋体"); //控件的字体

3.设置属性值

  1. //3.设置属性值
  2. [Category("General"), Description("Show Percent Tag"), Browsable(true)]
  3. public bool ShowPercentTag
  4. {
  5. get { return showPercent; }
  6. set
  7. {
  8. showPercent = value;
  9. Invalidate();
  10. }
  11. }
  12. [Category("General"), Description("Control's Maximum"), Browsable(true)]
  13. public int Maximum
  14. {
  15. get { return maximum; }
  16. set
  17. {
  18. maximum = value;
  19. Invalidate();
  20. }
  21. }
  22. [Category("General"), Description("Control's Minimum"), Browsable(true)]
  23. public int Minimum
  24. {
  25. get { return minimum; }
  26. set
  27. {
  28. minimum = value;
  29. Invalidate();
  30. }
  31. }
  32.  
  33. [Category("General"), Description("Control's FontSize"), Browsable(true)]
  34. public float FontSize
  35. {
  36. get { return fontSize; }
  37. set
  38. {
  39. this.fontSize = value;
  40. Invalidate();
  41. }
  42. }
  43. [Category("General"), Description("Control's FontFamily"), Browsable(true)]
  44. public FontFamily MyFontFamily
  45. {
  46. get { return myFontFamily; }
  47. set
  48. {
  49. this.myFontFamily = value;
  50. Invalidate();
  51. }
  52. }
  53.  
  54. [Category("Color"), Browsable(true)]
  55. public Color BackgroundColor
  56. {
  57. get { return backgroundColor; }
  58. set
  59. {
  60. this.backgroundColor = value;
  61. Invalidate();
  62. }
  63. }
  64. [Category("Color"), Browsable(true)]
  65. public Color ForegroundColor
  66. {
  67. get { return foregroundColor; }
  68. set
  69. {
  70. this.foregroundColor = value;
  71. Invalidate();
  72. }
  73. }
  74. [Category("Color"), Browsable(true)]
  75. public Color SetRectColor
  76. {
  77. get { return setRectColor; }
  78. set
  79. {
  80. this.setRectColor = value;
  81. Invalidate();
  82. }
  83. }
  84. [Category("Color"), Browsable(true)]
  85. public Color FontColor
  86. {
  87. get { return fontColor; }
  88. set
  89. {
  90. this.fontColor = value;
  91. Invalidate();
  92. }
  93. }

4.确定控件的位置

  1. //4.确定控件的位置,我们根据 Width 和 Height 属性来确定矩形的位置,由于Control 类也有这两个属性,我们在前面加上new覆盖掉原有的属性
  2. [Category("General"), Description("Control's Width"), Browsable(true)]
  3. public new int Width
  4. {
  5. get { return base.Width; }
  6. set
  7. {
  8. base.Width = value;
  9. foreRect.X = backRect.X = base.Width / ;
  10. backRect.Width = base.Width * / ;
  11. foreRect.Width = (int)(myValue / maximum * backRect.Width);
  12. setRect.X = (int)(myValue / maximum * (backRect.Width - backRect.Height) + foreRect.X);
  13.  
  14. Invalidate();
  15. }
  16. }
  17. [Category("General"), Description("Control's Height"), Browsable(true)]
  18. public new int Height
  19. {
  20. get { return base.Height; }
  21. set
  22. {
  23. base.Height = value;
  24. foreRect.Height = backRect.Height = setRect.Height = setRect.Width = base.Height / ;
  25. foreRect.Y = backRect.Y = setRect.Y = base.Height / ;
  26. Invalidate();
  27. }
  28. }

5.Value值变化的属性

  1. //5.Value值变化的属性。当外部为该事件添加了响应函数时,事件就会生效,否则为OnValueChanged的值为null
  2. protected EventHandler OnValueChanged;
  3. public event EventHandler ValueChanged
  4. {
  5. add
  6. {
  7. if (OnValueChanged != null)
  8. {
  9. foreach (Delegate d in OnValueChanged.GetInvocationList())
  10. {
  11. if (object.ReferenceEquals(d, value)) { return; }
  12. }
  13. }
  14. OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value);
  15. }
  16. remove
  17. {
  18. OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value);
  19. }
  20. }

6.定义value属性值

  1. //6.定义Value的值。当Value值改变的时候,重新设置矩形的进度,控制块的位置,并且重绘控件
  2. //注意:Value属性内如果对进度条的值进行修改,使用myValue变量,而在其他地方,则用Value属性
  3. [Category("General"), Description("Control's Value"), Browsable(true)]
  4. public double Value
  5. {
  6. get { return myValue; }
  7. set
  8. {
  9. if (myValue < Minimum)
  10. throw new ArgumentException("小于最小值");
  11. if (myValue > Maximum)
  12. throw new ArgumentException("超过最大值");
  13.  
  14. myValue = value;
  15. foreRect.Width = (int)(myValue / maximum * backRect.Width);
  16. setRect.X = (int)(myValue / maximum * (backRect.Width - backRect.Height) + backRect.X);
  17.  
  18. if ((myValue - maximum) > )
  19. {
  20. foreRect.Width = backRect.Width;
  21. setRect.X = backRect.Width - backRect.Height + backRect.X;
  22. }
  23.  
  24. //如果添加了响应函数,则执行该函数
  25. if (OnValueChanged != null)
  26. {
  27. OnValueChanged(this, EventArgs.Empty);
  28. }
  29.  
  30. Invalidate();
  31. }
  32. }

7.绘制控件

  1. //7.绘制控件,重载OnPaint方法对控件进行绘制
  2. protected override void OnPaint(PaintEventArgs pe)
  3. {
  4. base.OnPaint(pe);
  5.  
  6. DrawRect(pe.Graphics);
  7. DrawText(pe.Graphics);
  8. }
  9.  
  10. private void DrawRect(Graphics e)
  11. {
  12. Pen pen = new Pen(this.foregroundColor);
  13.  
  14. e.FillRectangle(new SolidBrush(this.backgroundColor), backRect);
  15. e.DrawRectangle(new Pen(Color.Black), backRect);
  16.  
  17. e.FillRectangle(new SolidBrush(this.foregroundColor), foreRect);
  18. e.DrawRectangle(new Pen(Color.Black), foreRect);
  19.  
  20. e.FillRectangle(new SolidBrush(this.setRectColor), setRect);
  21. e.DrawRectangle(new Pen(Color.Black), setRect);
  22. }
  23. private void DrawText(Graphics e)
  24. {
  25. Point point = new Point();
  26. point.X = this.backRect.X + this.backRect.Width * / ;
  27. point.Y = this.backRect.Y + this.backRect.Height / ;
  28.  
  29. SolidBrush brush = new SolidBrush(fontColor);
  30. Font font = new Font(myFontFamily, this.fontSize);
  31. string percent = ((int)this.myValue).ToString() + "%";
  32.  
  33. //通过设置StringFormat可以让文字居中显示
  34. StringFormat format = new StringFormat();
  35. format.Alignment = StringAlignment.Center;
  36. format.LineAlignment = StringAlignment.Center;
  37.  
  38. e.DrawString(percent, font, brush, backRect, format);
  39. }

8.在设计时,修改控件的大小

  1. //8.最后还有一个方法OnResize,在设计时,修改控件的大小会调用这个方法,比如:拖动边缘的箭头改变控件的大小时,控件也要做相应的改变时,就可以重载该方法,如果没有重载,就只有在修改完成后才更新控件,不懂的可以自己试一下
  2. protected override void OnResize(EventArgs e)
  3. {
  4. base.OnResize(e);
  5. this.Width = Width;
  6. this.Height = Height;
  7. Invalidate();
  8. }

9.1响应鼠标事件

  1. public MySlider()
  2. {
  3. //1.设置控件Style
  4.  
  5. //9.1.控件绘制完了,却不能操作,还要对控件进行操作
  6. //通过三个鼠标事件函数,让鼠标可以拖动控制条
  7. this.MouseDown += MySlider_MouseDown;
  8. this.MouseMove += MySlider_MouseMove;
  9. this.MouseUp += MySlider_MouseUp;
  10. }

9.2响应鼠标事件

  1. //9.2.添加三个辅助变量,添加响应函数
  2. Point originPoint;
  3. Point originsetRectPoint;
  4. bool setRectDown = false;
  5.  
  6. void MySlider_MouseUp(object sender, MouseEventArgs e)
  7. {
  8. setRectDown = false;
  9. }
  10. void MySlider_MouseMove(object sender, MouseEventArgs e)
  11. {
  12. if (setRectDown)
  13. {
  14. int dd = e.Location.X - originPoint.X;
  15.  
  16. double percent = (double)(originsetRectPoint.X + dd - this.backRect.X) / (this.backRect.Width - this.backRect.Height);
  17. if (percent < )
  18. {
  19. this.Value = minimum;
  20. this.foreRect.Width = ;
  21. this.setRect.X = backRect.X;
  22. }
  23. else if (percent > )
  24. {
  25. this.Value = maximum;
  26. this.foreRect.Width = this.backRect.Width;
  27. this.setRect.X = backRect.X + backRect.Width - backRect.Height;
  28. }
  29. else
  30. {
  31. this.Value = percent * maximum;
  32. this.foreRect.Width = (int)(percent * this.backRect.Width);
  33. this.setRect.X = originsetRectPoint.X + dd;
  34. }
  35. Invalidate();
  36. }
  37. }
  38. void MySlider_MouseDown(object sender, MouseEventArgs e)
  39. {
  40. if (setRect.Contains(e.Location))
  41. {
  42. this.originPoint = e.Location;
  43. originsetRectPoint = this.setRect.Location;
  44. this.setRectDown = true;
  45. }
  46. }

【Winform-自定义控件】一个自定义的进度条的更多相关文章

  1. Android 自定义水平进度条的圆角进度

    有时项目中需要实现水平圆角进度,如下两种,其实很简单     下面开始看代码,先从主界面布局开始看起: <?xml version="1.0" encoding=" ...

  2. iOS开发:代码通用性以及其规范 第二篇(猜想iOS中实现TableView内部设计思路(附代码),以类似的思想实现一个通用的进度条)

    在iOS开发中,经常是要用到UITableView的,我曾经思考过这样一个问题,为什么任何种类的model放到TableView和所需的cell里面,都可以正常显示?而我自己写的很多view却只是能放 ...

  3. 自定义环形进度条RoundProgressBar

    一.效果图: Canvas画圆环说明: 圆环宽度不必在意,只是画笔宽度设置后达到的效果. 二.实现步骤 1.自定义View-RoundProgressBar 2.设置属性resources(decle ...

  4. 【Android 应用开发】 自定义 圆形进度条 组件

    转载著名出处 : http://blog.csdn.net/shulianghan/article/details/40351487 代码下载 : -- CSDN 下载地址 : http://down ...

  5. Qt自定义控件系列(一) --- 圆形进度条

    本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

  6. ProgressBar学习笔记,自定义横向进度条的样式(包含ActionBar上面的进度条)

     点显示进度条后→   android:max="100" 进度条的最大值 android:progress  进度条已经完成的进度值 android:progressDrawab ...

  7. iOS开发:代码通用性以及其规范 第一篇(附带,自定义UITextView\进度条\双表显示\瀑布流 代码设计思路)

    在iOS团队开发中,我见过一些人的代码,也修改过他们的代码.有的人的代码写的非常之规范.通用,几乎不用交流,就可以知道如何修改以及在它基础上扩展延生.有的人的代码写的很垃圾,一眼看过去,简直会怀疑自己 ...

  8. 用初中数学知识撸一个canvas环形进度条

    周末好,今天给大家带来一款接地气的环形进度条组件vue-awesome-progress.近日被设计小姐姐要求实现这么一个环形进度条效果,大体由四部分组成,分别是底色圆环,进度弧,环内文字,进度圆点. ...

  9. android新闻项目、饮食助手、下拉刷新、自定义View进度条、ReactNative阅读器等源码

    Android精选源码 Android仿照36Kr官方新闻项目课程源码 一个优雅美观的下拉刷新布局,众多样式可选 安卓版本的VegaScroll滚动布局 android物流详情的弹框 健身饮食记录助手 ...

随机推荐

  1. Leaf Sets CodeForces - 1042F (树,最小划分)

    大意: 给定树, 求叶子的最小划分, 使得每个划分内任意两个叶子距离不超过k. 任选一个非叶结点, 贪心合并. #include <iostream> #include <sstre ...

  2. 怎样理解DOM

    一句话总结: DOM 是一个 js 对象. 他可以赋予 js 控制 html 文档的能力.  全称: Document Object Model. DOM 的最小组成单位是: 节点 , 节点有7种类型 ...

  3. 对接外网post,get接口封装类库

    public class HttpHelper { public static string GetAsync(string url)  { HttpWebRequest request = WebR ...

  4. 【原创】大叔经验分享(70)marathon重启app后一直处于waiting状态

    marathon重启app后一直处于waiting状态,查看marathon日志 # journalctl -u marathon -f 有如下日志: Jun 14 12:58:38 DataOne- ...

  5. qq快捷打开聊天窗口的代码

    pc代码: http://wpa.qq.com/msgrd?v=3&uin=8423291&site=qq&menu=yes

  6. js中with的作用

    js中with的作用当一个对象有多个需要操作的属性或方法时,可以使用如<体>试验<script type=“text/javascript”>var o=文件.创建元素(“DI ...

  7. HTML的学习(注释)

    <!--charset 编码字符集--> <!--UTF-8 万国码 gb2312 中国标准第2312条 中文,韩文....大部分的亚裔语言(繁体字不支持) GBK 在上面的基础之上 ...

  8. javascript&jquery方法比对

    参考链接:https://juejin.im/post/5d2705d8e51d4577407b1dda 参考评论链接http://youmightnotneedjquery.com/ javascr ...

  9. WebApi 跨域解决方案 --CORS

    跨站HTTP请求(Cross-site HTTP request)是指发起请求的资源所在域不同于请求指向的资源所在域的HTTP请求. 比如说,我在Web网站A(www.a.com)中通过<img ...

  10. git统计某个时间段写的代码行数

    1. 任务需要 领导想每个迭代统计一下,当前迭代开发的代码数量是多少 2. 解决方法 git log --stat --since=2019-09-12 --until=2019-09-27 | pe ...