官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

准备工作

这个用到GDI+画的,请先了解一下GDI+

还有用到了基类控件UCControlBase来控制圆角和背景色,如果还不了解请移步查看

(一)c#Winform自定义控件-基类控件

另外用到了水波控件UCWave,如果不了解请移步查看

(四十四)c#Winform自定义控件-水波

开始

添加一个用户控件UCProcessWave,继承UCControlBase

一些属性

   private bool m_isRectangle = false;
[Description("是否矩形"), Category("自定义")]
public bool IsRectangle
{
get { return m_isRectangle; }
set
{
m_isRectangle = value;
if (value)
{
base.ConerRadius = ;
}
else
{
base.ConerRadius = Math.Min(this.Width, this.Height);
}
}
}
#region 不再使用的父类属性 English:Parent class attributes that are no longer used
[Browsable(false)]
public new int ConerRadius
{
get;
set;
}
[Browsable(false)]
public new bool IsRadius
{
get;
set;
} [Browsable(false)]
public new Color FillColor
{
get;
set;
}
#endregion [Description("值变更事件"), Category("自定义")]
public event EventHandler ValueChanged;
int m_value = ;
[Description("当前属性"), Category("自定义")]
public int Value
{
set
{
if (value > m_maxValue)
m_value = m_maxValue;
else if (value < )
m_value = ;
else
m_value = value;
if (ValueChanged != null)
ValueChanged(this, null);
ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
Refresh();
}
get
{
return m_value;
}
} private int m_maxValue = ; [Description("最大值"), Category("自定义")]
public int MaxValue
{
get { return m_maxValue; }
set
{
if (value < m_value)
m_maxValue = m_value;
else
m_maxValue = value;
Refresh();
}
} public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
}
} public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
}
} [Description("值颜色"), Category("自定义")]
public Color ValueColor
{
get { return this.ucWave1.WaveColor; }
set
{
this.ucWave1.WaveColor = value;
}
} [Description("边框宽度"), Category("自定义")]
public override int RectWidth
{
get
{
return base.RectWidth;
}
set
{
if (value < )
base.RectWidth = ;
else
base.RectWidth = value;
}
}

构造函数一些设置

  public UCProcessWave()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
base.IsRadius = true;
base.IsShowRect = false;
RectWidth = ;
RectColor = Color.White;
ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
this.SizeChanged += UCProcessWave_SizeChanged;
this.ucWave1.OnPainted += ucWave1_Painted;
base.ConerRadius = Math.Min(this.Width, this.Height);
}

重绘

  protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SetGDIHigh();
if (!m_isRectangle)
{
//这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
SolidBrush solidBrush = new SolidBrush(Color.White);
e.Graphics.DrawEllipse(new Pen(solidBrush, ), new Rectangle(-, -, this.Width + , this.Height + ));
}
string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / , (this.Height - sizeF.Height) / + ));
}

波形控件重绘时处理

   void ucWave1_Painted(object sender, PaintEventArgs e)
{
e.Graphics.SetGDIHigh();
if (IsShowRect)
{
if (m_isRectangle)
{
Color rectColor = RectColor;
Pen pen = new Pen(rectColor, (float)RectWidth);
Rectangle clientRectangle = new Rectangle(, this.ucWave1.Height - this.Height, this.Width, this.Height);
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, , , 180f, 90f);
graphicsPath.AddArc(clientRectangle.Width - - , clientRectangle.Y, , , 270f, 90f);
graphicsPath.AddArc(clientRectangle.Width - - , clientRectangle.Bottom - - , , , 0f, 90f);
graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - - , , , 90f, 90f);
graphicsPath.CloseFigure();
e.Graphics.DrawPath(pen, graphicsPath);
}
else
{
SolidBrush solidBrush = new SolidBrush(RectColor);
e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(, this.ucWave1.Height - this.Height, this.Width, this.Height));
}
} if (!m_isRectangle)
{
//这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
SolidBrush solidBrush1 = new SolidBrush(Color.White);
e.Graphics.DrawEllipse(new Pen(solidBrush1, ), new Rectangle(-, this.ucWave1.Height - this.Height - , this.Width + , this.Height + ));
}
string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / , (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / ));
}

不知道你们有没有注意这句话

 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡

因为设置原价导致了区域毛边,所有画个没有毛边的边框覆盖之

完整代码

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D; namespace HZH_Controls.Controls
{
public partial class UCProcessWave : UCControlBase
{
private bool m_isRectangle = false;
[Description("是否矩形"), Category("自定义")]
public bool IsRectangle
{
get { return m_isRectangle; }
set
{
m_isRectangle = value;
if (value)
{
base.ConerRadius = ;
}
else
{
base.ConerRadius = Math.Min(this.Width, this.Height);
}
}
}
#region 不再使用的父类属性 English:Parent class attributes that are no longer used
[Browsable(false)]
public new int ConerRadius
{
get;
set;
}
[Browsable(false)]
public new bool IsRadius
{
get;
set;
} [Browsable(false)]
public new Color FillColor
{
get;
set;
}
#endregion [Description("值变更事件"), Category("自定义")]
public event EventHandler ValueChanged;
int m_value = ;
[Description("当前属性"), Category("自定义")]
public int Value
{
set
{
if (value > m_maxValue)
m_value = m_maxValue;
else if (value < )
m_value = ;
else
m_value = value;
if (ValueChanged != null)
ValueChanged(this, null);
ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
Refresh();
}
get
{
return m_value;
}
} private int m_maxValue = ; [Description("最大值"), Category("自定义")]
public int MaxValue
{
get { return m_maxValue; }
set
{
if (value < m_value)
m_maxValue = m_value;
else
m_maxValue = value;
Refresh();
}
} public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
}
} public override Color ForeColor
{
get
{
return base.ForeColor;
}
set
{
base.ForeColor = value;
}
} [Description("值颜色"), Category("自定义")]
public Color ValueColor
{
get { return this.ucWave1.WaveColor; }
set
{
this.ucWave1.WaveColor = value;
}
} [Description("边框宽度"), Category("自定义")]
public override int RectWidth
{
get
{
return base.RectWidth;
}
set
{
if (value < )
base.RectWidth = ;
else
base.RectWidth = value;
}
} public UCProcessWave()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
base.IsRadius = true;
base.IsShowRect = false;
RectWidth = ;
RectColor = Color.White;
ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
this.SizeChanged += UCProcessWave_SizeChanged;
this.ucWave1.OnPainted += ucWave1_Painted;
base.ConerRadius = Math.Min(this.Width, this.Height);
} void ucWave1_Painted(object sender, PaintEventArgs e)
{
e.Graphics.SetGDIHigh();
if (IsShowRect)
{
if (m_isRectangle)
{
Color rectColor = RectColor;
Pen pen = new Pen(rectColor, (float)RectWidth);
Rectangle clientRectangle = new Rectangle(, this.ucWave1.Height - this.Height, this.Width, this.Height);
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, , , 180f, 90f);
graphicsPath.AddArc(clientRectangle.Width - - , clientRectangle.Y, , , 270f, 90f);
graphicsPath.AddArc(clientRectangle.Width - - , clientRectangle.Bottom - - , , , 0f, 90f);
graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - - , , , 90f, 90f);
graphicsPath.CloseFigure();
e.Graphics.DrawPath(pen, graphicsPath);
}
else
{
SolidBrush solidBrush = new SolidBrush(RectColor);
e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(, this.ucWave1.Height - this.Height, this.Width, this.Height));
}
} if (!m_isRectangle)
{
//这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
SolidBrush solidBrush1 = new SolidBrush(Color.White);
e.Graphics.DrawEllipse(new Pen(solidBrush1, ), new Rectangle(-, this.ucWave1.Height - this.Height - , this.Width + , this.Height + ));
}
string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / , (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / ));
} void UCProcessWave_SizeChanged(object sender, EventArgs e)
{
if (!m_isRectangle)
{
base.ConerRadius = Math.Min(this.Width, this.Height);
if (this.Width != this.Height)
{
this.Size = new Size(Math.Min(this.Width, this.Height), Math.Min(this.Width, this.Height));
}
}
} protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.SetGDIHigh();
if (!m_isRectangle)
{
//这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
SolidBrush solidBrush = new SolidBrush(Color.White);
e.Graphics.DrawEllipse(new Pen(solidBrush, ), new Rectangle(-, -, this.Width + , this.Height + ));
}
string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / , (this.Height - sizeF.Height) / + ));
}
}
}
 namespace HZH_Controls.Controls
{
partial class UCProcessWave
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region 组件设计器生成的代码 /// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.ucWave1 = new HZH_Controls.Controls.UCWave();
this.SuspendLayout();
//
// ucWave1
//
this.ucWave1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ucWave1.Location = new System.Drawing.Point(, );
this.ucWave1.Name = "ucWave1";
this.ucWave1.Size = new System.Drawing.Size(, );
this.ucWave1.TabIndex = ;
this.ucWave1.Text = "ucWave1";
this.ucWave1.WaveColor = System.Drawing.Color.FromArgb(((int)(((byte)()))), ((int)(((byte)()))), ((int)(((byte)()))));
this.ucWave1.WaveHeight = ;
this.ucWave1.WaveSleep = ;
this.ucWave1.WaveWidth = ;
//
// UCProcessWave
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)()))), ((int)(((byte)()))), ((int)(((byte)()))));
this.Controls.Add(this.ucWave1);
this.Name = "UCProcessWave";
this.Size = new System.Drawing.Size(, );
this.ResumeLayout(false); } #endregion private UCWave ucWave1;
}
}

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

(四十六)c#Winform自定义控件-水波进度条-HZHControls的更多相关文章

  1. (三十八)c#Winform自定义控件-圆形进度条-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  2. (四十)c#Winform自定义控件-开关-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  3. NeHe OpenGL教程 第四十六课:全屏反走样

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. 四十六、android中的Bitmap

    四十六.android中的Bitmap: http://www.cnblogs.com/linjiqin/archive/2011/12/28/2304940.html 四十七.实现调用Android ...

  5. Android简易实战教程--第四十六话《RecyclerView竖向和横向滚动》

    Android5.X后,引入了RecyclerView,这个控件使用起来非常的方便,不但可以完成listView的效果,而且还可以实现ListView无法实现的效果.当然,在新能方便也做了大大的提高. ...

  6. “全栈2019”Java第四十六章:继承与字段

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  7. 第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么

    第四十六个知识点 在Sigma协议中,正确性,公正性和零知识性意味着什么 Sigma协议 Sigma协议是Alice想要向Bob证明一些东西的协议(Alice知道一些秘密).他们有下面的一般范式:Al ...

  8. (四十五)c#Winform自定义控件-水波图表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  9. (四十一)c#Winform自定义控件-进度条

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

随机推荐

  1. IUSEP研修报告

    目录 Introduction Alberta - Edmonton University of Alberta IUSEP Schoolwork and Project Principle of F ...

  2. AQS系列(五)- CountDownLatch的使用及原理

    前言 前面四节学完了AQS最难的两种重入锁应用,下面两节进入实战学习,看看JUC包中其他的工具类是如何运用AQS实现特定功能的.今天一起看一下CountDownLatch. CountDownLatc ...

  3. html5+css3的神奇搭配

    1.关于浮动 浮动的元素会脱离标准文档流(float),从而不占据空间,实现了一行排列多个元素的效果 ,但是又导致上级元素height消失,处理这种情况的方法就是有两种: 1.第一种在css里写个伪类 ...

  4. 程序员offer沟通的4个基本原则

     常柱 架构未来  你需要就一份新工作进行沟通时:比如你的薪水.福利,或者我个人最喜欢的每周工作时间缩短等,当公司问你“你想要多少?”或者“这是我们的报价,你说呢?” 最后关于薪资的谈话可能是最伤脑筋 ...

  5. 权值初始化 - Xavier和MSRA方法

    设计好神经网络结构以及loss function 后,训练神经网络的步骤如下: 初始化权值参数 选择一个合适的梯度下降算法(例如:Adam,RMSprop等) 重复下面的迭代过程: 输入的正向传播 计 ...

  6. 如何正确使用 Spring Cloud?【上】

    如何更快地交付软件,每周.每天甚至每个小时向用户发布新特性?如何让新员工在入职后就能部署代码?在如此快的节奏下如何保证质量?快,我们应用开发面临的主要挑战,交付越快就越能紧密地收集到用户反馈,从而更有 ...

  7. monkey命令解析详解

      我面试时遇到过几次让背个monkey命令的,可以这样简单说一个:adb shell monkey -p(约束包名) -s 200 -v -v --throttle 300 1500000 > ...

  8. k8s采坑记 - 证书过期之kubeadm重新生成证书

    重新生成证书 证书备份 cp -rp /etc/kubernetes /etc/kubernetes.bak 移除过期证书 rm -f /etc/kubernetes/pki/apiserver* r ...

  9. ubuntu 18.04 安装并配置adb

    获取最新的adb包 wget https://dl.google.com/android/repository/platform-tools-latest-linux.zip 将软件包解压到指定位置 ...

  10. .net上传文件,大文件及下载方式汇总(转)

    原文地址:http://www.360doc.com/content/19/1219/10/67993814_880731215.shtml Brettle.Web.NeatUpload.dll 文件 ...