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

 效果如下:

简单谈下设计思路:

应该说绘制上和下的标尺没有分别.左和右的标尺无非就是绘制文字和刻度时横纵坐标的调整而已.绘制刻度的单位是象素.因为很可能在以后的使用中会同时需要使用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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值