0.选择基类

 public class MySlider : Control

1.设置控件的Style

  在构造函数里添加:

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

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

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

3.设置属性值

        //3.设置属性值
[Category("General"), Description("Show Percent Tag"), Browsable(true)]
public bool ShowPercentTag
{
get { return showPercent; }
set
{
showPercent = value;
Invalidate();
}
}
[Category("General"), Description("Control's Maximum"), Browsable(true)]
public int Maximum
{
get { return maximum; }
set
{
maximum = value;
Invalidate();
}
}
[Category("General"), Description("Control's Minimum"), Browsable(true)]
public int Minimum
{
get { return minimum; }
set
{
minimum = value;
Invalidate();
}
} [Category("General"), Description("Control's FontSize"), Browsable(true)]
public float FontSize
{
get { return fontSize; }
set
{
this.fontSize = value;
Invalidate();
}
}
[Category("General"), Description("Control's FontFamily"), Browsable(true)]
public FontFamily MyFontFamily
{
get { return myFontFamily; }
set
{
this.myFontFamily = value;
Invalidate();
}
} [Category("Color"), Browsable(true)]
public Color BackgroundColor
{
get { return backgroundColor; }
set
{
this.backgroundColor = value;
Invalidate();
}
}
[Category("Color"), Browsable(true)]
public Color ForegroundColor
{
get { return foregroundColor; }
set
{
this.foregroundColor = value;
Invalidate();
}
}
[Category("Color"), Browsable(true)]
public Color SetRectColor
{
get { return setRectColor; }
set
{
this.setRectColor = value;
Invalidate();
}
}
[Category("Color"), Browsable(true)]
public Color FontColor
{
get { return fontColor; }
set
{
this.fontColor = value;
Invalidate();
}
}

4.确定控件的位置

//4.确定控件的位置,我们根据 Width 和 Height 属性来确定矩形的位置,由于Control 类也有这两个属性,我们在前面加上new覆盖掉原有的属性
[Category("General"), Description("Control's Width"), Browsable(true)]
public new int Width
{
get { return base.Width; }
set
{
base.Width = value;
foreRect.X = backRect.X = base.Width / ;
backRect.Width = base.Width * / ;
foreRect.Width = (int)(myValue / maximum * backRect.Width);
setRect.X = (int)(myValue / maximum * (backRect.Width - backRect.Height) + foreRect.X); Invalidate();
}
}
[Category("General"), Description("Control's Height"), Browsable(true)]
public new int Height
{
get { return base.Height; }
set
{
base.Height = value;
foreRect.Height = backRect.Height = setRect.Height = setRect.Width = base.Height / ;
foreRect.Y = backRect.Y = setRect.Y = base.Height / ;
Invalidate();
}
}

5.Value值变化的属性

//5.Value值变化的属性。当外部为该事件添加了响应函数时,事件就会生效,否则为OnValueChanged的值为null
protected EventHandler OnValueChanged;
public event EventHandler ValueChanged
{
add
{
if (OnValueChanged != null)
{
foreach (Delegate d in OnValueChanged.GetInvocationList())
{
if (object.ReferenceEquals(d, value)) { return; }
}
}
OnValueChanged = (EventHandler)Delegate.Combine(OnValueChanged, value);
}
remove
{
OnValueChanged = (EventHandler)Delegate.Remove(OnValueChanged, value);
}
}

6.定义value属性值

//6.定义Value的值。当Value值改变的时候,重新设置矩形的进度,控制块的位置,并且重绘控件
//注意:Value属性内如果对进度条的值进行修改,使用myValue变量,而在其他地方,则用Value属性
[Category("General"), Description("Control's Value"), Browsable(true)]
public double Value
{
get { return myValue; }
set
{
if (myValue < Minimum)
throw new ArgumentException("小于最小值");
if (myValue > Maximum)
throw new ArgumentException("超过最大值"); myValue = value;
foreRect.Width = (int)(myValue / maximum * backRect.Width);
setRect.X = (int)(myValue / maximum * (backRect.Width - backRect.Height) + backRect.X); if ((myValue - maximum) > )
{
foreRect.Width = backRect.Width;
setRect.X = backRect.Width - backRect.Height + backRect.X;
} //如果添加了响应函数,则执行该函数
if (OnValueChanged != null)
{
OnValueChanged(this, EventArgs.Empty);
} Invalidate();
}
}

7.绘制控件

        //7.绘制控件,重载OnPaint方法对控件进行绘制
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe); DrawRect(pe.Graphics);
DrawText(pe.Graphics);
} private void DrawRect(Graphics e)
{
Pen pen = new Pen(this.foregroundColor); e.FillRectangle(new SolidBrush(this.backgroundColor), backRect);
e.DrawRectangle(new Pen(Color.Black), backRect); e.FillRectangle(new SolidBrush(this.foregroundColor), foreRect);
e.DrawRectangle(new Pen(Color.Black), foreRect); e.FillRectangle(new SolidBrush(this.setRectColor), setRect);
e.DrawRectangle(new Pen(Color.Black), setRect);
}
private void DrawText(Graphics e)
{
Point point = new Point();
point.X = this.backRect.X + this.backRect.Width * / ;
point.Y = this.backRect.Y + this.backRect.Height / ; SolidBrush brush = new SolidBrush(fontColor);
Font font = new Font(myFontFamily, this.fontSize);
string percent = ((int)this.myValue).ToString() + "%"; //通过设置StringFormat可以让文字居中显示
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center; e.DrawString(percent, font, brush, backRect, format);
}

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

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

9.1响应鼠标事件

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

9.2响应鼠标事件

        //9.2.添加三个辅助变量,添加响应函数
Point originPoint;
Point originsetRectPoint;
bool setRectDown = false; void MySlider_MouseUp(object sender, MouseEventArgs e)
{
setRectDown = false;
}
void MySlider_MouseMove(object sender, MouseEventArgs e)
{
if (setRectDown)
{
int dd = e.Location.X - originPoint.X; double percent = (double)(originsetRectPoint.X + dd - this.backRect.X) / (this.backRect.Width - this.backRect.Height);
if (percent < )
{
this.Value = minimum;
this.foreRect.Width = ;
this.setRect.X = backRect.X;
}
else if (percent > )
{
this.Value = maximum;
this.foreRect.Width = this.backRect.Width;
this.setRect.X = backRect.X + backRect.Width - backRect.Height;
}
else
{
this.Value = percent * maximum;
this.foreRect.Width = (int)(percent * this.backRect.Width);
this.setRect.X = originsetRectPoint.X + dd;
}
Invalidate();
}
}
void MySlider_MouseDown(object sender, MouseEventArgs e)
{
if (setRect.Contains(e.Location))
{
this.originPoint = e.Location;
originsetRectPoint = this.setRect.Location;
this.setRectDown = true;
}
}

【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. Gluster的搭建和使用

    Gluster的搭建和使用 序言 我们为什么要去使用分布式存储,在一家大型公司或者大规模的集群中,大家可能会经常遇到一个问题,我的数据怎么存放,放在那,数据空间不够了怎么办,这些问题经常困扰着我们. ...

  2. 换发型app任性扣费?苹果app订阅任性扣费?怎么办?刚成功

    2019年9月18日17:09:27 什么黑猫举报没用 先关闭订阅 账户中心自助申请试试,不通过再进行下面这步 https://getsupport.apple.com/?caller=home&am ...

  3. 【opencv源码解析】 二、 cvtColor

    这里以CV_BGR2YUV_I420来讲 1. opencv244 core.cpp void cv::cvtColor( InputArray _src, OutputArray _dst, int ...

  4. 设计模式及UML图

    UML图 1. 依赖关系

  5. vue移动端出现遮罩层时在遮罩层滑动时禁止遮罩层下方页面滑动

    h5页面 点击出现弹框时 在遮罩层上面滑动时 下方的页面会出现滑动现象 解决方法 我知道的有以下两种 在遮罩层标签上添加@touchmove.prevent 把遮罩层显示时把下方的父盒子css设置为固 ...

  6. 公众平台第三方平台 .NET开发

    前言:本博客借鉴了很多三方内容整理的,参考博客:竹叶苿. 一.开发的目的(以下是引用官方的话) 公众平台第三方平台 是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台(并且可 ...

  7. 批量转换epub书籍为mobi电子书

    kindlegen下载地址: http://kindlegen.s3.amazonaws.com/kindlegen_win32_v2_9.zip 原文: http://blog.sina.com.c ...

  8. Ubuntu 16.04 装机后如何永久更改ulimit和修改MySQL的存储路径datadir

    Ubuntu 16.04 装机后的配置要点: 1. 网络的配置 2. 更改源列表 3. 永久更改ulimit ulimit限制着程序打开文件的数目,默认情况下为1024,作为服务器使用时,这个数字往往 ...

  9. Asp.Net Zero轻量级审核流设计

    复杂的业务系统中往往会集成工作流或审核流,但有些轻量及的业务系统对这些功能的需求并不大,有的系统甚至只需要审核功能就够了.这里给大家介绍在Asp.Net Zero中通用轻量及审核流设计,功能具备审核权 ...

  10. 移动端css适配

    /* iphoneX.iphoneXs */ @media only screen and (device-width: 375px) and (device-height: 812px) and ( ...