C#中添加自制控件

先看最终成品为一个可以在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为实际的绘图画布大小

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


        }

下面附完整代码:

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

        }
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值