绘制普通的可上下左右布局的RULER

    技术2022-05-11  69

     效果如下:

    简单谈下设计思路:

    应该说绘制上和下的标尺没有分别.左和右的标尺无非就是绘制文字和刻度时横纵坐标的调整而已.绘制刻度的单位是象素.因为很可能在以后的使用中会同时需要使用dock = top和dock = left的两个标尺,组成坐标系,所以为了使他们的点不交叉,提供了一个MoveValue的属性,让他们的原点移动指定值后开始绘制.因为绘制的方法很简单, 下面直接给出代码:

    源代码如下:

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Text;using System.Windows.Forms;using System.Drawing.Drawing2D;using System.Globalization;using System.IO;namespace JcsControlLibrary{    public partial class JcsRuler : Panel    {        //一般版式的format        StringFormat format = new StringFormat(StringFormat.GenericTypographic);        private int _ScaleValue;//刻度转换基数        private int _BaseStep;//最小刻度的基数        private int _NextSmallScale;//次小刻度的基数        private int _BigScale;//最长刻度线的基数        private int _ShowNumberScale;//显示数字的基数        private DrawUnit _DrawUnit;//单位        private float Stroke = 3;//绘制一笔的基数        private int RulerLength;//尺的长度        //private int RulerWidth = 21;//适合宽度或高度        private int _MoveValue = 21;//原点移动调整值        private LayoutType _LayoutType = LayoutType.NoneLayout;//布局状态        private bool _IsShowNumber = true;//是否显示数值        private Color _NextScaleColor = Color.Black ;//次小刻度的颜色        private Color _BigScaleColor = Color.Black;//最大刻度的颜色        private Color _BaseStepColor = Color.Black;//最小基本刻度的颜色        private Color _NumberColor = Color.Black; //刻度值的颜色        private bool _IsShowUnitCaption = false;//是否显示单位标题        //private bool _IsBorder

            #region"Enum"            /// <summary>        /// 布局状态        /// </summary>        public enum LayoutType        {            HorizontalTop,            HorizontalBottom,            VerticalLeft,            VerticalRight,            NoneLayout        }        /// <summary>        /// 绘制的单位(象素,厘米,英寸)        /// </summary>        public enum DrawUnit        {            Pixels,            Cm,            Inch        }        #endregion

            public JcsRuler()        {            InitializeComponent();            this.RulerLength = this.Width;            format.FormatFlags = StringFormatFlags.NoWrap;            format.Trimming = StringTrimming.Character;        }

            #region"Property"        /// <summary>        /// 绘制刻度时候的放大基数(不允许为非正数)        /// </summary>        [CategoryAttribute("JcsControl属性"), DescriptionAttribute("绘制刻度的放大基数")]        public float BaseStroke        {            get             {                return this.Stroke;            }            set             {                if (value <= 0)                {                    throw new Exception("绘制刻度的放大基数不允许为0或负数!");                }                this.Stroke = value;                this.Invalidate();            }        }        /// <summary>        /// 当前应用的绘制单位        /// </summary>        [CategoryAttribute("JcsControl属性"), DescriptionAttribute("当前应用的绘制单位")]        public DrawUnit CurrenDrawtUnit        {            get            {                return this._DrawUnit ;            }            set            {                this._DrawUnit = value;                this.Invalidate();            }        }        /// <summary>        /// 是否绘制刻度值        /// </summary>        [Category("JcsControl属性"),Description("是否绘制刻度值"),DefaultValue(true)]        public bool IsDrawNumber        {            get            {                return this._IsShowNumber;            }            set            {                this._IsShowNumber = value;                this.Invalidate();            }        }        /// <summary>        /// 最小刻度的颜色        /// </summary>        [Category("JcsControl属性"), Description("最小刻度的颜色"),DefaultValue(typeof(Color), "Black")]        public Color BaseStepColor        {            get            {                return this._BaseStepColor ;            }            set            {                this._BaseStepColor = value;                this.Invalidate();            }        }        /// <summary>        /// 次小刻度的颜色        /// </summary>        [Category("JcsControl属性"), Description("次小刻度的颜色"),DefaultValue(typeof(Color), "Black")]        public Color NextScaleColor        {            get            {                return this._NextScaleColor;            }            set            {                this._NextScaleColor = value;                this.Invalidate();            }        }        /// <summary>        /// 最大刻度的颜色        /// </summary>        [Category("JcsControl属性"), Description("最大刻度的颜色"),DefaultValue(typeof(Color), "Black")]        public Color BigScaleColor        {            get            {                return this._BigScaleColor ;            }            set            {                this._BigScaleColor = value;                this.Invalidate();            }        }        /// <summary>        /// 刻度数值的颜色        /// </summary>        [Category("JcsControl属性"), Description("刻度数值的颜色"),DefaultValue(typeof(Color),"Black")]        public Color NumberColor        {            get            {                return this._NumberColor;            }            set            {                this._NumberColor = value;                this.Invalidate();            }        }        /// <summary>        /// 是否显示当前单位标题        /// </summary>        [Category("JcsControl属性"), Description("是否显示当前单位标题"),DefaultValue(false)]        public bool IsShowUnitCaption        {            get             {                return this._IsShowUnitCaption;            }            set             {                this._IsShowUnitCaption = value;                this.Invalidate();            }        }        /// <summary>        /// 原点移动调整值        /// </summary>        [Category("JcsControl属性"), Description("原点移动调整值"), DefaultValue(21)]        public int MoveValue        {            get            {                return this._MoveValue ;            }            set            {                this._MoveValue = value;                this.Invalidate();            }        }        #endregion

            protected override void OnPaint(PaintEventArgs e)        {            base.OnPaint(e);            drawruler(e.Graphics);        }        private void drawruler(Graphics g)        {            switch (this._DrawUnit)            {                case DrawUnit.Pixels :                    _BaseStep = 5;                    _NextSmallScale = 10;                    _BigScale = 50;                    _ShowNumberScale = 100;                    _ScaleValue = 1;                    break;                case DrawUnit.Cm:                    g.PageUnit = GraphicsUnit.Millimeter;                    g.PageScale = 1f;                    _BaseStep = 1;                    _NextSmallScale = 5;                    _BigScale = 10;                    _ShowNumberScale = 10;                    _ScaleValue = 10;                    break;                case DrawUnit.Inch :                    g.PageUnit = GraphicsUnit.Inch;                    g.PageScale = 1f / 12f;                    _BaseStep = 1;                    _NextSmallScale = 2;                    _BigScale = 6;                    _ShowNumberScale = 12;                    _ScaleValue = 12;                    break;            }

                //PointF[] point = new PointF[] {            //    new PointF(2, 2), new PointF(5, 5), new Point(this.Size), this.Location};

                进行坐标系的转换,从驱动坐标,也就是通常以象素为坐标的坐标系向世界坐标转换(目标坐标,源坐标,点集合)            //g.TransformPoints(CoordinateSpace.World, CoordinateSpace.Device, point);

                switch (this._LayoutType)            {                case LayoutType.NoneLayout:                    DrawRulerAtLayoutTop(g);                    break;                case LayoutType.HorizontalTop:                    DrawRulerAtLayoutTop(g);                    break;                case LayoutType.HorizontalBottom:                    DrawRulerAtLayoutTop(g);                    break;                case LayoutType.VerticalLeft:                    DrawRulerAtLayoutLeft(g);                    break;                case LayoutType.VerticalRight:                    DrawRulerAtLayoutRight(g);                    break;            }                   }        private void DrawRulerAtLayoutTop(Graphics g)        {            //ControlPaint.DarkDark(SystemColors.ControlDarkDark);            ControlPaint.DrawBorder3D(g, new Rectangle(0, 0, this.Width, this.Height / 2));            for (int i = 0; i < RulerLength; i += _BaseStep)            {                float d = 1;//最小刻度的线长默认为1                using (Pen pen = new Pen(Color.Black, 1.8f))                {                    pen.Color = this._BaseStepColor;                    if (i % _NextSmallScale == 0)                    {                        if (i % _BigScale == 0)                        {                            d = 3;//最大线长为3                            pen.Color = this._BigScaleColor;                        }                        else                        {                            d = 2;//次小线长为2                            pen.Color = this._NextScaleColor;                        }                    }                    g.DrawLine(pen, i + _MoveValue, 0f, i + _MoveValue, d * Stroke);                }                if (this._IsShowNumber)                {                    if ((i % _ShowNumberScale) == 0)                    {                        //获取不依赖区域特性的字符                        string text = (i / _ScaleValue).ToString(CultureInfo.InvariantCulture);                        SizeF size = g.MeasureString(text, this.Font, RulerLength, this.format);                        using (SolidBrush b = new SolidBrush(this._NumberColor))                        {                            g.DrawString(text, this.Font,b, i + _MoveValue - size.Width / 2, d * Stroke, this.format);                        }                    }                }                if (this._IsShowUnitCaption)                {                    string text = this.GetDrawUnitString(_DrawUnit);                    SizeF size = g.MeasureString(text, this.Font, RulerLength, this.format);                    if (this._MoveValue > size.Width+1)                    {                        using (SolidBrush b = new SolidBrush(this._NumberColor))                        {                            g.DrawString(text, this.Font, b, 1, 1, this.format);                        }                    }                }            }        }        private void DrawRulerAtLayoutLeft(Graphics g)        {            for (int i = 0; i < RulerLength; i += _BaseStep)            {                float d = 1;//最小刻度的线长默认为1                using (Pen pen = new Pen(Color.Black, 1.8f))                {                    pen.Color = this._BaseStepColor;                    if (i % _NextSmallScale == 0)                    {                        if (i % _BigScale == 0)                        {                            d = 3;//最大线长为3                            pen.Color = this._BigScaleColor;                        }                        else                        {                            d = 2;//次小线长为2                            pen.Color = this._NextScaleColor ;                        }                    }                    g.DrawLine(pen, this.Width - d * Stroke, i + _MoveValue, this.Width, i + _MoveValue);                }                if (this._IsShowNumber)                {                    if ((i % _ShowNumberScale) == 0)                    {                        //获取不依赖区域特性的字符                        string text = (i / _ScaleValue).ToString(CultureInfo.InvariantCulture);                        SizeF size = g.MeasureString(text, this.Font, RulerLength, this.format);                        using (SolidBrush b = new SolidBrush(this._NumberColor))                        {                            g.DrawString(text, this.Font, b, this.Width - d * Stroke - size.Width, i + _MoveValue - size.Height / 2, this.format);                        }                    }                }            }        }        private void DrawRulerAtLayoutRight(Graphics g)        {            for (int i = 0; i < RulerLength; i += _BaseStep)            {                float d = 1;//最小刻度的线长默认为1                using (Pen pen = new Pen(Color.Black, 1.8f))                {                    pen.Color = this._BaseStepColor;                    if (i % _NextSmallScale == 0)                    {                        if (i % _BigScale == 0)                        {                            d = 3;//最大线长为3                            pen.Color = this._BigScaleColor;                        }                        else                        {                            d = 2;//次小线长为2                            pen.Color = this._NextScaleColor ;                        }                    }                                   g.DrawLine(pen, 0, i + _MoveValue, d * Stroke, i + _MoveValue);                }                if (this._IsShowNumber)                {                    if ((i % _ShowNumberScale) == 0)                    {                        //获取不依赖区域特性的字符                        string text = (i / _ScaleValue).ToString(CultureInfo.InvariantCulture);                        SizeF size = g.MeasureString(text, this.Font, RulerLength, this.format);                        using (SolidBrush b = new SolidBrush(this._NumberColor))                        {                            g.DrawString(text, this.Font,b, d * Stroke, i + _MoveValue - size.Height / 2, this.format);                        }                    }                }            }        }        private void GetRulerWidth()        {            switch (this.Dock)            {                case DockStyle.Top:                    this._LayoutType = LayoutType.HorizontalTop;                    this.RulerLength = this.Width;                    break;                case DockStyle.Left:                    this._LayoutType = LayoutType.VerticalLeft;                    this.RulerLength = this.Height;                    break;                case DockStyle.Right:                    this._LayoutType = LayoutType.VerticalRight;                    this.RulerLength = this.Height;                    break;                case DockStyle.Bottom:                    this._LayoutType = LayoutType.HorizontalBottom;                    this.RulerLength = this.Width;                    break;                case DockStyle.None:                    if (this.Width >= this.Height)                    {                        this._LayoutType = LayoutType.NoneLayout;                        this.RulerLength = this.Width;                        break;                    }                    else                    {                        this._LayoutType = LayoutType.NoneLayout;                        this.RulerLength = this.Height;                        break;                    }                               }                  }        private string GetDrawUnitString(DrawUnit u)        {            string returnstring = null;            if (u == DrawUnit.Inch)            {                returnstring = "In";            }            else if(u == DrawUnit.Cm )            {                returnstring = "Cm";            }            else if (u == DrawUnit.Pixels )            {                returnstring = "Px";            }            return returnstring;        }

            protected override void OnResize(EventArgs eventargs)        {            base.OnResize(eventargs);            this.GetRulerWidth();        }    }}


    最新回复(0)