自定义控件:组合控件,实现导航菜单的功能
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,特别注意:

