C#--自定义控件-导航菜单(自定义事件,属性)

自定义控件:组合控件,实现导航菜单的功能

1,属性

经过分析控件功能,有以下属性

【1.1】导航栏图片:Image NaviImage

【1.2】导航按钮名:String NaviName

【1.3】是否激活:Bool IsActive

【1.4】激活滑块变距:Int ActiveGap

【1.5】激活方块高度:Int ActiveHeight

【1.6】激活方块颜色:Color ActiveColor

【1.7】悬浮的渐变色系数:Float ColorDepth

【1.8】权限:Int Role

【1.9】单击事件:ClickEvent

2,添加用户控件

添加“用户控件”

注意:字体和大小要与主窗体一致,要不然会导致拖入后大小不匹配的情况

3,UI设计

让Label标签字体永远在下方,居中显示,的设置

 

 

 4,添加属性

【4.1】哪些属性需要propfull,哪些属性只用prop就可以,取决于这个属性是否要实时刷新

5,添加事件

【5.1】

 

 6,代码如下:

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Jason_Controls
{
    //【自定义事件步骤3:最关键的设置,被调用的时候,默认就是调用这个ClickEvent事件】
    [DefaultEvent("ClickEvent")]
    public partial class NaviButton : UserControl
    {
        public NaviButton()
        {
            InitializeComponent();
            SaveBackColor = this.BackColor;
        }

        private Color SaveBackColor;

        private Image naviImage=Properties.Resources.首页_32黑色;//一定要有个默认设置,要不然后面使用的时候,一直是null
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("导航按钮图片设置")]
        public Image NaviImage
        {
            get { return naviImage; }
            set
            {
                naviImage = value;
                this.pic_main.Image = naviImage;
            }
        }

        private String naviName = "实时监控";
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("导航按钮名称设置")]
        public String NaviName
        {
            get { return naviName; }
            set
            {
                naviName = value;
                this.lbl_naviName.Text = naviName;
            }
        }

        private bool isActive = false;
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("导航按钮是否激活")]
        public bool IsActive
        {
            get { return isActive; }
            set
            {
                isActive = value;
                this.Invalidate();//重绘
            }
        }

        private int activeGap = 0;
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("激活方块边距")]
        public int ActiveGap
        {
            get { return activeGap; }
            set
            {
                activeGap = value;
                this.Invalidate();//重绘
            }
        }

        private int activeHeight = 4;
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("激活方块高度")]
        public int ActiveHeight
        {
            get { return activeHeight; }
            set
            {
                activeHeight = value;
                this.Invalidate();//重绘
            }
        }

        private Color activeColor = Color.FromArgb(236,250,243);
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("激活方块的颜色")]
        public Color ActiveColor
        {
            get { return activeColor; }
            set
            {
                activeColor = value;
                this.Invalidate();//重绘
            }
        }

        //这个属性不用实时刷新,就不需要propfull来设置属性了
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("权限等级")]
        public int Role { get; set; } = 0;

        private void NvaiButton_Load(object sender, EventArgs e)
        {

        }

        //【自定义事件步骤1:自定义一个Event】
        [Browsable(true)]
        [Category("Jason自定义事件")]
        [Description("导航按钮的单击事件")]
        public event EventHandler ClickEvent;

        //【自定义事件步骤2:什么时候调用这个事件】
        private void lbl_naviName_Click(object sender, EventArgs e)
        {
            if (ClickEvent != null)
            {
                ClickEvent.Invoke(this,e);//【特别注意】第一个参数要用this,因为后面判断的时候要用,this就是指这个当前自定义控件NaviButton。
                                          //(如果后面不用判断,参数都无所谓,用sender或null都可以)
                //ClickEvent.Invoke(sender,e);//【如果参数是sender,去点击的时候sender对应的就是这个Label标签】
            }
        }

        private void pic_main_Click(object sender, EventArgs e)
        {
            if (ClickEvent != null)
            {
                ClickEvent.Invoke(this, e);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics graphics = e.Graphics;
            //画矩形
            Rectangle rectangle = new Rectangle(activeGap, this.Height - activeHeight, this.Width - 2 * activeGap, activeHeight);
            if (IsActive)
            { 
                graphics.FillRectangle(new SolidBrush(this.activeColor)  ,rectangle);
            }
            else
            {
                graphics.FillRectangle(new SolidBrush(this.BackColor), rectangle);
            }

        }

        #region 渐变色设置

        //这个属性不用实时刷新,就不需要propfull来设置属性了
        [Browsable(true)]
        [Category("Jason自定义属性")]
        [Description("悬浮渐变色系数")]
        public float ColorDepth { get; set; } = -0.2f;

        //鼠标放上去,变色
        private void lbl_naviName_MouseEnter(object sender, EventArgs e)
        {
            this.BackColor = ChangeColor(this.BackColor, ColorDepth);
        }

        //鼠标移走,变回原有的颜色
        private void lbl_naviName_MouseLeave(object sender, EventArgs e)
        {
            this.BackColor = SaveBackColor;
        }

        /// <summary>
        /// 通用的颜色渐变方法:在某个颜色基础上,添加一个修正系数(-1到1之间)
        /// </summary>
        /// <param name="color"></param>
        /// <param name="correctionFactor"></param>
        /// <returns></returns>
        private Color ChangeColor(Color color, float correctionFactor)
        {
            if (correctionFactor > 1.0f) correctionFactor = 1.0f;
            if (correctionFactor < -1.0f) correctionFactor = -1.0f;

            float red = (float) color.R;
            float green = (float) color.G;
            float blue = (float) color.B;

            if (correctionFactor < 0)
            {
                correctionFactor = 1 + correctionFactor;
                red *= correctionFactor;
                green *= correctionFactor;
                blue *= correctionFactor;
            }
            else
            {
                red = (255 - red) * correctionFactor + red;
                green = (255 - green) * correctionFactor + green;
                blue = (255 - blue) * correctionFactor + blue;
            }

            if (red < 0) red = 0;
            if (red > 255) red = 255;
            if (green < 0) green = 0;
            if (green > 255) green = 255;
            if (blue < 0) blue = 0;
            if (blue > 255) blue = 255;
            return Color.FromArgb(color.A, (int) red, (int) green, (int) blue);
        }

        #endregion

 
    }
}

  

 

 7,特别注意:

 

 

 

 

posted @ 2021-11-29 09:26  包子789654  阅读(1619)  评论(0编辑  收藏  举报