.NET 自定义Button控件(二)

继续前一节的内容,本节将介绍自定义Button控件。代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace JFormControl
{
    public class JControlBase:Control
    {
        public JControlBase() : base()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0085 || m.Msg == 0x000F || m.Msg == 0x0007 || m.Msg == 0x0005)
            {
                Invalidate();
            }
            base.WndProc(ref m);
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing;
using System.ComponentModel;
namespace JFormControl
{
    public class JButton:JControlBase
    {
        private int edgeWidth = 0;
        public struct Angle
        {
            public const float Up = 50F;
            public const float Down = Angle.Up + 180F;
            public const float Defualt = 60F;
        }

        public JButton()
        {
           
        }
        #region EllipseAlign
        private ControlEllipseAlign eAlignt = ControlEllipseAlign.Right;
        /// <summary>
        /// 设置椭圆方向
        /// </summary>
        [Browsable(true),Category("杂项"),Description("获取和设置椭圆的方向")]
        public ControlEllipseAlign EllipseAlign
        {
            set
            {
                if(eAlignt!=value)
                {
                    eAlignt = value;
                    Invalidate();
                }
            }
            get
            {
                return this.eAlignt;
            }
        }
        #endregion

        #region EllipseAngle
        private float fAngle=.0f;
        /// <summary>
        /// 获取和设置椭圆幅度
        /// </summary>
        [Browsable(true), Category("杂项"), Description("获取和设置椭圆幅度")]
        public float EllipseAngle
        {
            set
            {
                this.fAngle = value;
            }
            get
            {
                return this.fAngle;
            }
        }

        #endregion

        #region RecessDepth
        private int iRecessDepth = 0;
        public int RecessDepth
        {
            set
            {
                this.iRecessDepth = value;
                Invalidate();
            }
            get
            {
                return this.iRecessDepth;
            }
        }
        #endregion

        #region lightAngle
        private float lightAngle = Angle.Defualt;
        public float LightAngle
        {
            set
            {
                this.lightAngle = value;
                Invalidate();
            }
            get
            {
                return this.lightAngle;
            }
        }
        #endregion

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle rect = this.ClientRectangle;
            edgeWidth = GetEdgeWidth(rect);
            Graphics g = e.Graphics;
           
            //画背景色
            FillBackColor(e.Graphics, rect);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            //
            if (RecessDepth > 0)
            {
                DrawRecess(g, ref rect);
            }
            DrawEdges(g, ref rect);

 

 

 

        }

        #region FillBackColor
        private void FillBackColor(Graphics g, Rectangle rect)
        {
            SolidBrush sBrush = new SolidBrush(this.Parent.BackColor);
            rect.Inflate(1, 1);
            g.FillRectangle(sBrush, rect);
            sBrush.Dispose();
        }
        #endregion
        #region DrawRecess
        protected virtual void DrawRecess(Graphics g, ref Rectangle recessRect)
        {

            LinearGradientBrush recessBrush = new LinearGradientBrush(recessRect,
                                                ControlPaint.Dark(Parent.BackColor),
                                                ControlPaint.LightLight(Parent.BackColor),
                                                GetLightAngle(Angle.Up));
            Blend recessBlend = new Blend();
            recessBlend.Positions = new float[] { 0.0f, .2f, .4f, .6f, .8f, 1.0f };
            recessBlend.Factors = new float[] { .2f, .2f, .4f, .4f, 1f, 1f };
            recessBrush.Blend = recessBlend;

            Rectangle rect2 = recessRect;
            ShrinkShape(ref rect2, 1);
            GraphicsPath gPath = CreateGraphicsPath(rect2);
            g.FillPath(recessBrush, gPath);
            recessBrush.Dispose();
            gPath.Dispose();
            ShrinkShape(ref recessRect, iRecessDepth);

        }
        #endregion

        #region DrawEdges
        protected virtual void DrawEdges(Graphics g, ref Rectangle edgeRect)
        {
            ShrinkShape( ref edgeRect, 1);

            Rectangle lgbRect = edgeRect;
            lgbRect.Inflate(1, 1);
            LinearGradientBrush edgeBrush = new LinearGradientBrush(lgbRect,
                                                ControlPaint.LightLight(BackColor),
                                                ControlPaint.DarkDark(BackColor),
                                                GetLightAngle(lightAngle));
            // Blend colours for realism
            Blend edgeBlend = new Blend();
            edgeBlend.Positions = new float[] { 0.0f, .2f, .4f, .6f, .8f, 1.0f };
            edgeBlend.Factors = new float[] { .0f, .0f, .2f, .4f, 1f, 1f };
            edgeBrush.Blend = edgeBlend;
            GraphicsPath gPath = CreateGraphicsPath(lgbRect);
            g.FillPath(edgeBrush, gPath);
            edgeBrush.Dispose();
            gPath.Dispose();
            ShrinkShape(ref edgeRect, edgeWidth);
        }
        #endregion

        #region Method
        protected float GetLightAngle(float angle)
        {
            float f = 1 - (float)this.Width / this.Height;        // Calculate proportions of button
            float a = angle - (15 * f);       // Move virtual light source accordingly
            return a;
        }
        private void ShrinkShape(ref Rectangle rect, int amount)
        {
            rect.Inflate(-amount, -amount);
        }
        protected int GetEdgeWidth(Rectangle rect)
        {
            if (rect.Width < 50 | rect.Height < 50) return 1;
            else return 2;
        }
        #endregion

        #region CreateGraphicsPath
        /// <summary>
        /// 创建控件路径
        /// </summary>
        /// <param name="r"></param>
        /// <returns></returns>
        private GraphicsPath CreateGraphicsPath(Rectangle r)
        {
            float x0 = (float)r.X;
            float y0 = (float)r.Y;
            float width = (float)r.Width / 10;
            float height = (float)r.Height;
            float x1 = (float)(x0 + width * 9);
            float y1 = (float)(y0 + height);

            GraphicsPath gPaths = new GraphicsPath();
            switch (this.eAlignt)
            {
                case ControlEllipseAlign.Right:
                    gPaths.AddBezier(x0, y0, x0 + width, y0 + height / 4, x0 + width, y0 + height / 4 * 3, x0, y1);
                    gPaths.AddLine(x0, y0, x1, y0);
                    gPaths.AddBezier(x1, y0, x1 + width, y0 + height / 4, x1 + width, y0 + height / 4 * 3, x1, y1);
                    gPaths.AddLine(x1, y1, x0, y1);
                    break;
                case ControlEllipseAlign.Left:
                  
                    x1 = (float)(x0 + r.Width);
                    x0 = x0 + width ;
                    gPaths.AddBezier(x0, y0, x0 - width, y0 + height / 4, x0 - width, y0 + height / 4 * 3, x0, y1);
                    gPaths.AddLine(x0 , y0, x1, y0);
                    gPaths.AddBezier(x1, y0, x1 - width, y0 + height / 4, x1 - width, y0 + height / 4 * 3, x1, y1);
                    gPaths.AddLine(x1, y1, x0 , y1);
                    break;
            }
            gPaths.CloseFigure();
            return gPaths;
        }
        #endregion
    }
    /// <summary>
    /// 设置控件椭圆方向
    /// </summary>
    public enum ControlEllipseAlign:short
    {
        Right=0,
        Left,
      
    }
}

 运行结果:

运行结果

主要的方法在于创建控件路径和填充的角度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值