先看最终成品为一个可以在XY坐标系下,进行点位显示的控件
制作过程:
1.添加用户控件类
2.进入代码编辑页面
套路式开发:继承 UserControl public partial class PointCurve : UserControl
初始化过程:
public PointCurve()
{
InitializeComponent();
//设置控件样式
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); //减少闪烁
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //启用双缓冲技术
this.SetStyle(ControlStyles.ResizeRedraw, true); //根据窗口大小的重新绘制指令
this.SetStyle(ControlStyles.Selectable, true);//激活与用户的交互响应
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);//支持透明背景色
this.SetStyle(ControlStyles.UserPaint, true); //用户自己控制绘制
}
画图类绘制对象的三大件:
//画布
private Graphics g;
//画笔
private Pen p;
//画刷
private SolidBrush sb;
控件属性:(显示在加载进入工具箱后的属性界面)
/****************原点****************************************/
private int orginGap = 20; //内部调用数值
[Browsable(true)] //在属性界面显示
[Category("自定义属性")] //分组类别
[Description("原点坐标")] //显示名称
public int OriginGap //外部用户交互变量
{
get { return orginGap; }
set
{
if (value <= 0)
{
return;
}
orginGap = value;
this.Invalidate(); //外部改变后重新绘制
}
}
/****************X轴最大值****************************************/
private float maxXAxis = 70000.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("X轴最大值")]
public float MaxXAxis
{
get { return maxXAxis; }
set { maxXAxis = value;
this.Invalidate(); //重新绘制
}
}
/****************Y轴最大值****************************************/
private float maxYAxis = 70000.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("Y轴最大坐标值")]
public float MaxYAxis
{
get { return maxYAxis; }
set { maxYAxis = value;
this.Invalidate(); //重新绘制
}
}
/****************位置坐标1X轴坐标****************************************/
[Browsable(true)]
[Category("自定义属性")]
[Description("位置坐标1X轴坐标")]
public int ReclaimerXAxis
{
get { return reclaimerXAxis; }
set
{
reclaimerXAxis = value;
this.Invalidate();
}
}
/****************位置坐标1Y轴坐标****************************************/
private int reclaimerYAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("位置坐标1Y轴坐标")]
public int ReclaimerYAxis
{
get { return reclaimerYAxis; }
set
{
reclaimerYAxis = value;
this.Invalidate();
}
}
……想显示多少个坐标点可以自由添加
/****************颜色属性添加****************************************/
private Color reclaimerColor = Color.Blue;
[Browsable(true)]
[Category("自定义属性")]
[Description("坐标点颜色")]
public Color ReclaimerColor
{
get { return reclaimerColor; }
set
{
reclaimerColor = value;
this.Invalidate();
}
}
/****************字符串属性添加****************************************/
private string reclaimerStr = "位置1";
[Browsable(true)]
[Category("自定义属性")]
[Description("位置1字符串")]
public string ReclaimerStr
{
get { return reclaimerStr; }
set
{
reclaimerStr = value;
this.Invalidate();
}
}
/****************绘制点直径属性添加****************************************/
private int pointdiameter = 5;
[Browsable(true)]
[Category("自定义属性")]
[Description("绘制点直径")]
public int Pointdiameter
{
get { return pointdiameter; }
set
{
pointdiameter = value;
this.Invalidate();
}
}
以上信息都是属性信息,不涉及逻辑,属于为了实现自己绘制目的而定义的成员变量
接下来重写的OnPaint函数是真正的绘制过程,每次用户改变属性信息时,由于执行了 this.Invalidate();,都会后台去调用OnPaint函数,从而实现位置更新。
下面函数中涉及一些计算过程,其实是由于窗体绘图默认原点是左上角,而我们习惯的坐标系原点的左下角,里面的计算过程是为了将我们输入的位置坐标进行转换的过程,无需过分纠结,理解原理,this.Height.,this.with为实际的绘图画布大小文章来源:https://www.toymoban.com/news/detail-761116.html
protected override void OnPaint(PaintEventArgs e) //执行重绘指令时会被调用
{
base.OnPaint(e);
//绘制过程
//绘制画布
g = e.Graphics;
//设置画布
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//消除锯齿
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//正式绘制
//设置画笔
p = new Pen(Color.Black, 1.5f);
p.CustomEndCap = new AdjustableArrowCap(p.Width * 3, p.Width * 4, true); //结束端采用箭头样式
//绘制X轴
g.DrawLine(p, new Point(orginGap, this.Height - orginGap), new Point(this.Width - orginGap, this.Height - orginGap));
//绘制Y轴
g.DrawLine(p, new Point(orginGap, this.Height - orginGap), new Point(orginGap, orginGap));
//绘制原点
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;//字符中心居中
sf.LineAlignment = StringAlignment.Center;//线中心居中
g.DrawString("0", this.Font, new SolidBrush(Color.Black), new Rectangle(0, this.Height - orginGap, orginGap, orginGap), sf);
//绘制X轴最大
g.DrawString(maxXAxis.ToString(), this.Font, new SolidBrush(Color.Black), new Rectangle(this.Width -50, this.Height -orginGap+5, 50, orginGap), sf);
//绘制Y轴最大
g.DrawString(maxYAxis.ToString(), this.Font, new SolidBrush(Color.Black), new Rectangle(0, 0, 50, orginGap), sf);
//绘制取料点
float reclaimerX = (this.Width - 2 * orginGap) / maxXAxis * reclaimerXAxis + orginGap;
float reclaimerY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * reclaimerYAxis + orginGap);
g.FillEllipse(new SolidBrush(reclaimerColor), new RectangleF(reclaimerX - 0.5f * pointdiameter, reclaimerY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(reclaimerStr, this.Font, new SolidBrush(reclaimerColor), new RectangleF(reclaimerX - 25.0f, reclaimerY - 20.0f, 50.0f, 20.0f), sf);
//绘制加工点
float processX = (this.Width - 2 * orginGap) / maxXAxis * processXAxis + orginGap;
float processY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * processYAxis + orginGap);
g.FillEllipse(new SolidBrush(processColor), new RectangleF(processX - 0.5f * pointdiameter, processY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(processStr, this.Font, new SolidBrush(processColor), new RectangleF(processX - 25.0f, processY - 20.0f, 50.0f, 20.0f), sf);
//绘制出料点
float outletX = (this.Width - 2 * orginGap) / maxXAxis * outletXAxis + orginGap;
float outletY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * outletYAxis + orginGap);
g.FillEllipse(new SolidBrush(outletColor), new RectangleF(outletX - 0.5f * pointdiameter, outletY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(outletStr, this.Font, new SolidBrush(outletColor), new RectangleF(outletX - 25.0f, outletY - 20.0f, 50.0f, 20.0f), sf);
}
下面附完整代码:文章来源地址https://www.toymoban.com/news/detail-761116.html
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApp1
{
public partial class PointCurve : UserControl
{
public PointCurve()
{
InitializeComponent();
//设置控件样式
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); //减少闪烁
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); //启用双缓冲技术
this.SetStyle(ControlStyles.ResizeRedraw, true); //根据窗口大小的重新绘制指令
this.SetStyle(ControlStyles.Selectable, true);//激活与用户的交互响应
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);//支持透明背景色
this.SetStyle(ControlStyles.UserPaint, true); //用户自己控制绘制
}
#region 绘制对象的创建
//画布
private Graphics g;
//画笔
private Pen p;
//画刷
private SolidBrush sb;
#endregion
#region 控件属性
private int orginGap = 20;
[Browsable(true)]
[Category("自定义属性")]
[Description("原点坐标")]
public int OriginGap
{
get { return orginGap; }
set
{
if (value <= 0)
{
return;
}
orginGap = value;
this.Invalidate(); //重新绘制
}
}
private float maxXAxis = 70000.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("X轴最大值")]
public float MaxXAxis
{
get { return maxXAxis; }
set { maxXAxis = value;
this.Invalidate(); //重新绘制
}
}
private float maxYAxis = 70000.0f;
[Browsable(true)]
[Category("自定义属性")]
[Description("Y轴最大坐标值")]
public float MaxYAxis
{
get { return maxYAxis; }
set { maxYAxis = value;
this.Invalidate(); //重新绘制
}
}
private int reclaimerXAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("取料口X轴坐标")]
public int ReclaimerXAxis
{
get { return reclaimerXAxis; }
set
{
reclaimerXAxis = value;
this.Invalidate();
}
}
private int reclaimerYAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("取料口Y轴坐标")]
public int ReclaimerYAxis
{
get { return reclaimerYAxis; }
set
{
reclaimerYAxis = value;
this.Invalidate();
}
}
private int processXAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("加工处X轴坐标")]
public int ProcessXAxis
{
get { return processXAxis; }
set
{
processXAxis = value;
this.Invalidate();
}
}
private int processYAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("加工处Y轴坐标")]
public int ProcessYAxis
{
get { return processYAxis; }
set
{
processYAxis = value;
this.Invalidate();
}
}
private int outletXAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("出料口X轴坐标")]
public int OutletXAxis
{
get { return outletXAxis; }
set
{
outletXAxis = value;
this.Invalidate();
}
}
private int outletYAxis = 0;
[Browsable(true)]
[Category("自定义属性")]
[Description("出料口Y轴坐标")]
public int OutletYAxis
{
get { return outletYAxis; }
set
{
outletYAxis = value;
this.Invalidate();
}
}
private Color reclaimerColor = Color.Blue;
[Browsable(true)]
[Category("自定义属性")]
[Description("取料口点颜色")]
public Color ReclaimerColor
{
get { return reclaimerColor; }
set
{
reclaimerColor = value;
this.Invalidate();
}
}
private Color processColor = Color.Green;
[Browsable(true)]
[Category("自定义属性")]
[Description("加工处点颜色")]
public Color ProcessColor
{
get { return processColor; }
set
{
processColor = value;
this.Invalidate();
}
}
private Color outletColor = Color.Red;
[Browsable(true)]
[Category("自定义属性")]
[Description("出料口点颜色")]
public Color OutletColor
{
get { return outletColor; }
set
{
outletColor = value;
this.Invalidate();
}
}
private string reclaimerStr = "取料口";
[Browsable(true)]
[Category("自定义属性")]
[Description("取料口字符串")]
public string ReclaimerStr
{
get { return reclaimerStr; }
set
{
reclaimerStr = value;
this.Invalidate();
}
}
private string processStr = "加工处";
[Browsable(true)]
[Category("自定义属性")]
[Description("加工处字符串")]
public string ProcessStr
{
get { return processStr; }
set
{
processStr = value;
this.Invalidate();
}
}
private string outletStr = "出料口";
[Browsable(true)]
[Category("自定义属性")]
[Description("出料口字符串")]
public string OutletStr
{
get { return outletStr; }
set
{
outletStr = value;
this.Invalidate();
}
}
private int pointdiameter = 5;
[Browsable(true)]
[Category("自定义属性")]
[Description("绘制点直径")]
public int Pointdiameter
{
get { return pointdiameter; }
set
{
pointdiameter = value;
this.Invalidate();
}
}
#endregion
protected override void OnPaint(PaintEventArgs e) //执行重绘指令时会被调用
{
base.OnPaint(e);
//绘制过程
//绘制画布
g = e.Graphics;
//设置画布
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//消除锯齿
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//正式绘制
//设置画笔
p = new Pen(Color.Black, 1.5f);
p.CustomEndCap = new AdjustableArrowCap(p.Width * 3, p.Width * 4, true); //结束端采用箭头样式
//绘制X轴
g.DrawLine(p, new Point(orginGap, this.Height - orginGap), new Point(this.Width - orginGap, this.Height - orginGap));
//绘制Y轴
g.DrawLine(p, new Point(orginGap, this.Height - orginGap), new Point(orginGap, orginGap));
//绘制原点
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;//字符中心居中
sf.LineAlignment = StringAlignment.Center;//线中心居中
g.DrawString("0", this.Font, new SolidBrush(Color.Black), new Rectangle(0, this.Height - orginGap, orginGap, orginGap), sf);
//绘制X轴最大
g.DrawString(maxXAxis.ToString(), this.Font, new SolidBrush(Color.Black), new Rectangle(this.Width -50, this.Height -orginGap+5, 50, orginGap), sf);
//绘制Y轴最大
g.DrawString(maxYAxis.ToString(), this.Font, new SolidBrush(Color.Black), new Rectangle(0, 0, 50, orginGap), sf);
//绘制取料点
float reclaimerX = (this.Width - 2 * orginGap) / maxXAxis * reclaimerXAxis + orginGap;
float reclaimerY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * reclaimerYAxis + orginGap);
g.FillEllipse(new SolidBrush(reclaimerColor), new RectangleF(reclaimerX - 0.5f * pointdiameter, reclaimerY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(reclaimerStr, this.Font, new SolidBrush(reclaimerColor), new RectangleF(reclaimerX - 25.0f, reclaimerY - 20.0f, 50.0f, 20.0f), sf);
//绘制加工点
float processX = (this.Width - 2 * orginGap) / maxXAxis * processXAxis + orginGap;
float processY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * processYAxis + orginGap);
g.FillEllipse(new SolidBrush(processColor), new RectangleF(processX - 0.5f * pointdiameter, processY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(processStr, this.Font, new SolidBrush(processColor), new RectangleF(processX - 25.0f, processY - 20.0f, 50.0f, 20.0f), sf);
//绘制出料点
float outletX = (this.Width - 2 * orginGap) / maxXAxis * outletXAxis + orginGap;
float outletY = this.Height - ((this.Height - 2 * orginGap) / maxYAxis * outletYAxis + orginGap);
g.FillEllipse(new SolidBrush(outletColor), new RectangleF(outletX - 0.5f * pointdiameter, outletY - 0.5f * pointdiameter, pointdiameter, pointdiameter));
g.DrawString(outletStr, this.Font, new SolidBrush(outletColor), new RectangleF(outletX - 25.0f, outletY - 20.0f, 50.0f, 20.0f), sf);
}
private void PointCurve_Load(object sender, EventArgs e)
{
}
}
}
到了这里,关于C#中添加自制控件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!