winform自定义箭头控件

效果:箭头效果图

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Windows.Forms;
using System.ComponentModel.Design;

namespace TestControls
{
    #region enum
    /// <summary>
    /// 颜色填充方向
    /// </summary>
    public enum LinearGradientDirection
    {
        Vertical,
        Horizontal
    }

    /// <summary>
    /// 箭头方向
    /// </summary>
    public enum ArrowStyleType
    {
        None,
        Left,
        Right,
        Top,
        Bottom,
        LeftRight,
        TopBottom,
        UpBow,
        DownBow,
        LeftBow,
        RightBow,
    }
    #endregion

    public partial class ArrowLine : System.Windows.Forms.Control
    {
        #region 变量
        //private System.ComponentModel.Container components = null;
        private PointF[] m_pnts = null;                              // 箭头点坐标
        GraphicsPath m_gp = new GraphicsPath();                      // 绘制路径
        private Color m_ColorS = Color.WhiteSmoke;                  // 起始渐变色
        private Color m_ColorE = Color.DarkGray;
        private Color m_NormalStartColor = Color.WhiteSmoke;      // 常规起始渐变色
        private Color m_NormalEndColor = Color.DarkGray;
        private LinearGradientDirection m_lgdirect = LinearGradientDirection.Horizontal;
        private ArrowStyleType m_ArrowType = ArrowStyleType.None; // 箭头类型
        private float m_ArrowLength = 8.0f;                       // 箭标长度
        private float m_ArrowBodyWidth = 8.0f;                    // 箭身宽度

        private float m_BowHeight = 4.0f;                         // 弓长度
        private float m_BowWidth = 4.0f;                          // 弓宽度
        private bool m_antiAlias = false;                         // 反走样绘制

        private bool m_FrameEnabled = false;
        private int m_pCount = 8;

        private const int MINSIZE = 2;                        // 最小大小
        #endregion

        #region 属性
        /// <summary>
        /// 开始渐变颜色
        /// </summary>
        public Color NormalStartColor
        {
            get { return m_NormalStartColor; }
            set { m_NormalStartColor = value; Refresh(); }
        }

        /// <summary>
        ///结束渐变颜色
        /// </summary>
        public Color NormalEndColor
        {
            get { return m_NormalEndColor; }
            set { m_NormalEndColor = value; Refresh(); }
        }

        /// <summary>
        /// 渐变色方向
        /// </summary>
        public LinearGradientDirection ColorLinearDirection
        {
            get { return m_lgdirect; }
            set { m_lgdirect = value; Refresh(); }
        }


        /// <summary>
        /// 是否有立体框架
        /// </summary>
        public bool FrameEnabled
        {
            get { return m_FrameEnabled; }
            set { m_FrameEnabled = value; Refresh(); }
        }

        /// <summary>
        /// 箭头类型
        /// </summary>
        public ArrowStyleType ArrowStyle
        {
            get { return m_ArrowType; }
            set
            {
                m_ArrowType = value;
                Clear();
                Init();
                Refresh();
            }
        }

        /// <summary>
        /// 箭标长度
        /// </summary>
        public float ArrowLength
        {
            get { return m_ArrowLength; }
            set
            {
                m_ArrowLength = value;
                // AdjustmentBodyWH();
                Clear();
                Init();
                Refresh();
            }
        }

        /// <summary>
        /// 箭身宽度
        /// </summary>
        public float ArrowBodyWidth
        {
            get { return m_ArrowBodyWidth; }
            set
            {
                m_ArrowBodyWidth = value;
                //AdjustmentBodyWH();
                Clear();
                Init();
                Refresh();
            }
        }

        /// <summary>
        /// 弓长度
        /// </summary>
        public float BowHeight
        {
            get { return m_BowHeight; }
            set
            {
                m_BowHeight = value;
                Clear();
                Init();
                Refresh();
            }
        }

        /// <summary>
        /// 弓宽度
        /// </summary>
        public float BowWidth
        {
            get { return m_BowWidth; }
            set
            {
                m_BowWidth = value;
                Clear();
                Init();
                Refresh();
            }
        }

        /// <summary>
        /// 反走样
        /// </summary>
        public bool AntiAlias
        {
            get { return m_antiAlias; }
            set
            {
                m_antiAlias = value;
                Clear();
                Init();
                Refresh();
            }
        }

        private bool m_LinearGradientUsingClient = true;  //渐变色使用客户区
        /// <summary>
        /// 渐变色使用是否只使用控件客户区
        /// </summary>
        public bool LinearGradientUsingClient
        {
            get { return m_LinearGradientUsingClient; }
            set
            {

                m_LinearGradientUsingClient = value;
                {
                    Clear();
                    Init();
                    Refresh();
                }
            }
        }

        private Rectangle m_LinearGradientRect;
        /// <summary>
        /// 渐变色使用区区域范围
        /// </summary>
        public Rectangle LinearGradientRect
        {
            get { return m_LinearGradientRect; }
            set
            {

                m_LinearGradientRect = value;
                {
                    Clear();
                    Init();
                    Refresh();
                }
            }
        }
        #endregion

        #region 构造函数
        public ArrowLine()
        {
            InitializeComponent();
            Init();

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.BackColor = Color.Transparent;

            m_LinearGradientRect = this.ClientRectangle;
        }

        public ArrowLine(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
        }
        #endregion

        #region 继承函数

        /// <summary>
        /// Resize
        /// </summary>
        /// <param name="e"></param>
        protected override void OnResize(EventArgs e)
        {
            Clear();
            Init();
            Refresh();
        }

        /// <summary>
        /// Paint
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            m_ColorS = NormalStartColor;
            m_ColorE = NormalEndColor;

            Rectangle rect = this.ClientRectangle;
            if (m_LinearGradientUsingClient)
            {
                rect = this.ClientRectangle;
            }
            else
            {
                rect = this.RectangleToClient(m_LinearGradientRect);
            }


            LinearGradientBrush b = null;
            if (ColorLinearDirection == LinearGradientDirection.Horizontal)
            {
                b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 0, false);
            }
            else
            {
                b = new LinearGradientBrush(rect, m_ColorS, m_ColorE, 90, false);
            }

            // 设计模式
            if (this.DesignMode != true)
            {
                e.Graphics.SetClip(m_gp);
            }

            //反走样
            if (m_antiAlias)
            {
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            }
            else
            {
                e.Graphics.SmoothingMode = SmoothingMode.None;
            }

            e.Graphics.FillPath(b, m_gp);  //填充路径
            b.Dispose();

            //划框
            if (m_FrameEnabled)
            {
                ColorArrowFrame(e);
            }
        }

        #endregion

        #region 方法

        private void Clear()
        {
            m_pnts = null;
            m_gp.Reset();
        }

        private void ColorArrowFrame(PaintEventArgs e)
        {
            Pen p1 = null;
            {
                if (this.Width < this.Height)
                {
                    for (int i = 0; i < m_pCount - 1; i++)
                    {
                        if (m_pnts[i].Y <= m_pnts[i + 1].Y)
                        {
                            p1 = new Pen(SystemColors.ControlLightLight, 1f);
                        }
                        else
                        {
                            p1 = new Pen(SystemColors.ControlDark, 1f);
                        }
                        e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
                    }
                }
                else
                {
                    for (int i = 0; i < m_pCount - 1; i++)
                    {
                        if (m_pnts[i].Y > m_pnts[i + 1].Y)
                        {
                            p1 = new Pen(SystemColors.ControlLightLight, 1f);
                        }
                        else
                        {
                            p1 = new Pen(SystemColors.ControlDark, 1f);
                        }
                        e.Graphics.DrawLine(p1, m_pnts[i].X, m_pnts[i].Y, m_pnts[i + 1].X, m_pnts[i + 1].Y);
                    }
                }
            }

        }

        /// <summary>
        /// Sequence to create the button
        /// </summary>
        private void Init()
        {
            MakeSquare();

            float dx = this.Width - 2;
            float dy = this.Height - 2;

            if (m_FrameEnabled == false)
            {
                dx = this.Width;
                dy = this.Height;
            }

            // 产生箭头坐标
            BuildInitialArrow();

            // 绘制
            GraphicsPathFromPoints(m_pnts, m_gp);

        }

        private void MakeSquare()
        {
            this.SuspendLayout();
            if (this.Width < MINSIZE)
            {
                this.Size = new Size(MINSIZE, MINSIZE);
            }
            else
            {
                //if ( this.Size.Width < this.Size.Height )
                //{
                //    this.Size = new Size ( this.Size.Width, this.Size.Width );
                //}
                //else
                //{
                //    this.Size = new Size ( this.Size.Height, this.Size.Height );
                //}
            }
            this.ResumeLayout();
        }

        /// <summary>
        /// 创建箭头点
        /// </summary>
        private void BuildInitialArrow()
        {
            // AdjustmentBodyWH();

            float dx = this.Width - 2;
            float dy = this.Height - 2;

            if (m_FrameEnabled == false)
            {
                dx = this.Width;
                dy = this.Height;
            }

            switch (m_ArrowType)
            {
                case ArrowStyleType.None:
                    m_pCount = 5;
                    m_pnts = new PointF[m_pCount];

                    m_pnts[0] = new PointF(0, 0);
                    m_pnts[1] = new PointF(dx, 0);
                    m_pnts[2] = new PointF(dx, dy);
                    m_pnts[3] = new PointF(0, dy);
                    m_pnts[4] = new PointF(0, 0);
                    break;
                case ArrowStyleType.Top:
                    m_pCount = 8;
                    m_pnts = new PointF[m_pCount];

                    m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
                    m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, m_ArrowLength);
                    m_pnts[2] = new PointF(0, m_ArrowLength);
                    m_pnts[3] = new PointF(dx / 2f, 0);
                    m_pnts[4] = new PointF(dx, m_ArrowLength);
                    m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
                    m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy);
                    m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy);
                    break;
                case ArrowStyleType.Left:
                    m_pCount = 8;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[1] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[2] = new PointF(m_ArrowLength, 0);
                    m_pnts[3] = new PointF(0, dy / 2f);
                    m_pnts[4] = new PointF(m_ArrowLength, dy);
                    m_pnts[5] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[6] = new PointF(dx, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[7] = new PointF(dx, dy / 2f - m_ArrowBodyWidth / 2f);
                    break;
                case ArrowStyleType.Right:
                    m_pCount = 8;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[1] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[2] = new PointF(dx - m_ArrowLength, 0);
                    m_pnts[3] = new PointF(dx, dy / 2f);
                    m_pnts[4] = new PointF(dx - m_ArrowLength, dy);
                    m_pnts[5] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[6] = new PointF(0, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[7] = new PointF(0, dy / 2f - m_ArrowBodyWidth / 2f);
                    break;
                case ArrowStyleType.Bottom:
                    m_pCount = 8;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
                    m_pnts[1] = new PointF((dx - m_ArrowBodyWidth) / 2f, dy - m_ArrowLength);
                    m_pnts[2] = new PointF(0, dy - m_ArrowLength);
                    m_pnts[3] = new PointF(dx / 2f, dy);
                    m_pnts[4] = new PointF(dx, dy - m_ArrowLength);
                    m_pnts[5] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
                    m_pnts[6] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, 0);
                    m_pnts[7] = new PointF((dx - m_ArrowBodyWidth) / 2f, 0);
                    break;
                case ArrowStyleType.LeftRight:
                    m_pCount = 11;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, dy / 2f);
                    m_pnts[1] = new PointF(m_ArrowLength, 0);
                    m_pnts[2] = new PointF(m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[3] = new PointF(dx - m_ArrowLength, dy / 2f - m_ArrowBodyWidth / 2f);
                    m_pnts[4] = new PointF(dx - m_ArrowLength, 0);
                    m_pnts[5] = new PointF(dx, dy / 2f);
                    m_pnts[6] = new PointF(dx - m_ArrowLength, dy);
                    m_pnts[7] = new PointF(dx - m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[8] = new PointF(m_ArrowLength, dy / 2f + m_ArrowBodyWidth / 2f);
                    m_pnts[9] = new PointF(m_ArrowLength, dy);
                    m_pnts[10] = new PointF(0, dy / 2f);
                    break;
                case ArrowStyleType.TopBottom:
                    m_pCount = 11;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(dx / 2f, dy);
                    m_pnts[1] = new PointF(0, dy - m_ArrowLength);
                    m_pnts[2] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
                    m_pnts[3] = new PointF(dx / 2f - m_ArrowBodyWidth / 2f, m_ArrowLength);
                    m_pnts[4] = new PointF(0, m_ArrowLength);
                    m_pnts[5] = new PointF(dx / 2f, 0);
                    m_pnts[6] = new PointF(dx, m_ArrowLength);
                    m_pnts[7] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, m_ArrowLength);
                    m_pnts[8] = new PointF(dx / 2f + m_ArrowBodyWidth / 2f, dy - m_ArrowLength);
                    m_pnts[9] = new PointF(dx, dy - m_ArrowLength);
                    m_pnts[10] = new PointF(dx / 2f, dy);
                    break;
                case ArrowStyleType.UpBow:
                    m_pCount = 9;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, 0);
                    m_pnts[1] = new PointF(0, dy);
                    m_pnts[2] = new PointF(dx, dy);
                    m_pnts[3] = new PointF(dx, 0);
                    m_pnts[4] = new PointF(dx - m_BowWidth, 0);
                    m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
                    m_pnts[6] = new PointF(m_BowWidth, dy - m_BowHeight);
                    m_pnts[7] = new PointF(m_BowWidth, 0);
                    m_pnts[8] = new PointF(0, 0);
                    break;
                case ArrowStyleType.DownBow:
                    m_pCount = 9;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, dy);
                    m_pnts[1] = new PointF(0, 0);
                    m_pnts[2] = new PointF(dx, 0);
                    m_pnts[3] = new PointF(dx, dy);
                    m_pnts[4] = new PointF(dx - m_BowWidth, dy);
                    m_pnts[5] = new PointF(dx - m_BowWidth, m_BowHeight);
                    m_pnts[6] = new PointF(m_BowWidth, m_BowHeight);
                    m_pnts[7] = new PointF(m_BowWidth, dy);
                    m_pnts[8] = new PointF(0, dy);
                    break;
                case ArrowStyleType.LeftBow:
                    m_pCount = 9;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, 0);
                    m_pnts[1] = new PointF(dx, 0);
                    m_pnts[2] = new PointF(dx, dy);
                    m_pnts[3] = new PointF(0, dy);
                    m_pnts[4] = new PointF(0, dy - m_BowHeight);
                    m_pnts[5] = new PointF(dx - m_BowWidth, dy - m_BowHeight);
                    m_pnts[6] = new PointF(dx - m_BowWidth, m_BowHeight);
                    m_pnts[7] = new PointF(0, m_BowHeight);
                    m_pnts[8] = new PointF(0, 0);
                    break;
                case ArrowStyleType.RightBow:
                    m_pCount = 9;
                    m_pnts = new PointF[m_pCount];
                    m_pnts[0] = new PointF(0, 0);
                    m_pnts[1] = new PointF(dx, 0);
                    m_pnts[2] = new PointF(dx, m_BowHeight);
                    m_pnts[3] = new PointF(m_BowWidth, m_BowHeight);
                    m_pnts[4] = new PointF(m_BowWidth, dy - m_BowHeight);
                    m_pnts[5] = new PointF(dx, dy - m_BowHeight);
                    m_pnts[6] = new PointF(dx, dy);
                    m_pnts[7] = new PointF(0, dy);
                    m_pnts[8] = new PointF(0, 0);
                    break;

                default:
                    break;
            }
        }


        private void GraphicsPathFromPoints(PointF[] pnts, GraphicsPath gp)
        {
            for (int i = 0; i < pnts.Length - 1; i++)
            {
                gp.AddLine(pnts[i].X, pnts[i].Y, pnts[i + 1].X, pnts[i + 1].Y);
            }
        }

        //protected override void PostFilterProperties(IDictionary Properties)
        //{
        //    Properties.Remove("AllowDrop");
        //    Properties.Remove("BackColor");
        //    Properties.Remove("BackgroundImage");
        //    Properties.Remove("ContextMenu");
        //    Properties.Remove("FlatStyle");
        //    Properties.Remove("Image");
        //    Properties.Remove("ImageAlign");
        //    Properties.Remove("ImageIndex");
        //    Properties.Remove("ImageList");
        //    Properties.Remove("TextAlign");
        //    Properties.Remove("Text");
        //    Properties.Remove("Enabled");
        //}
        #endregion
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值