一、效果图
效果图忘记移动到窗口边缘了,移动到窗口边缘会自动调整位置的。
二、说明
1、控件上还存在一点小问题,有知道解决方案的,请不吝赐教,多谢!
2、控件是绘制的,没有使用winform标准库中的控件。
3、控件是我在做其他软件时需要的,因此增加了Word中选色的功能。
4、还有几天就要考一建了,最近太忙只有晚上放松时间才写写代码,暂时没有时间检查修改小问题,后期上传了源码,有发下问题的请告知下,我有时间了会修改更新,上传代码估计要等到9月中旬我忙完了这段时间了。
5、参考内容:
1.颜色色相值计算:https://www.cnblogs.com/grenet/archive/2009/12/14/1623796.html,其实这个没啥用,但要知道原理,c#Color类有GetHue方法。
2.色彩空间:https://blog.csdn.net/qq_41375318/article/details/118550040
3.Windows画图软件和PS软件中颜色选择窗口
4.OpenXml的Color类:https://learn.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.wordprocessing.color?view=openxml-2.8.1
三、思路与存在的问题
1、控件分为两部分,一部分是在窗口中显示使用,一部分是弹出选择。
2、考虑到类似ComBox那样的弹出下拉列表,可以超出父窗口的范围。因此控件弹出层使用的是窗口,而不是控件。(不懂ComBox的效果原理,目前做出来的还是存在一点问题)
3、目前存在一个缺点就是,弹出颜色选择后,如果没有点击弹出层的情况下,直接点击控件所在窗口中无法获取焦点的控件(如:label),窗口不会自动隐藏。
4、请教大佬,有谁懂ComBox弹出层效果实现的原理,一定请私聊或评论中告诉我一下,跪谢了!!!
5、代码框架
控件在WordColor项目中,简单说明下类的作用吧
1.ColorPicker 类
控件显示类,就是在应用窗口显示的控件类。
2.Popup 类
控件弹出层类。
3.ColorValue 类
定义的WordColor类,Word中颜色的设置是由颜色、主题、阴影、亮度几个因素构成的,因此需要封装下。
4.CustomColorType 枚举
弹出层为“自定义颜色选择”时,显示的方式,与是否可以输入RGB或Html颜色进行调整的枚举。
5.DisplayType 枚举
弹出层的类型,一共有四种。
6.DispalyData 命名空间
弹出层显示的数据。
6.1 ColorPlateBase类
四种弹出层显示的基类。
6.2 HeightColor类
Word中高亮标记颜色选择类
6.3 ThemeColor类
Word中颜色选择类
6.4 CommonColor类
常用颜色选择类(参考率Windows自带画图软件的常用颜色)
6.5 CustomColor类
自定义颜色选择类,这个类最为麻烦
7.Ext 命名空间
扩展类。
7.1 ColorHelper类
颜色帮助类,主要是生成自定义颜色的色带,根据色带选中,生成对应颜色图。这里的计算方法是我根据PS中颜色选择的方法一步一步推导出的数学式计算出来的。在网上找了很久都没有找到,只能从0学习颜色的构成、色相度关系等,然后再推导公式。
7.2 DrawPath类
生成一些固定图形的类,比如生成三角形(正三角、倒三角、斜三角)、圆角矩形等
7.3 Number类
只有一个方法,就是将字符串转为32位整数
7.4 PointExt类
Point或Rectangle偏移方法,主要用到的是比例缩放、固定值缩放Rectangle等
7.5 Shifting类
Point或Rectangle偏移方法,包括左右偏移,大小偏移等
四、关键部分代码
1、ColorPicker类
#region ==声明委托==
/// <summary>
/// 声明选择颜色的委托
/// </summary>
/// <param name="c"></param>
public delegate void SelectedColor(object sender,Color? c);
/// <summary>
/// 定义弹出层完成事件
/// </summary>
/// <param name="o"></param>
public delegate void PopupedEvent(object sender);
/// <summary>
/// 点击更多颜色选择的按钮
/// </summary>
/// <param name="sender"></param>
public delegate void MoreBtnClick(object sender);
#endregion
public partial class ColorPicker : UserControl
{
#region ==私有成员===
/// <summary>
/// 颜色选择器样式
/// </summary>
private DisplayType displayType = DisplayType.HightColor;
/// <summary>
/// 默认的颜色值
/// </summary>
private ColorValue colorValue = new ColorValue(null,null);
/// <summary>
/// 弹出层对象
/// </summary>
private Popup? Popup;
/// <summary>
/// 选择后的颜色
/// </summary>
protected Rectangle ColorRect = Rectangle.Empty;
/// <summary>
/// 选择器中按钮部分
/// </summary>
protected Rectangle ColorBtnRect = Rectangle.Empty;
/// <summary>
/// 渐变设图像保存
/// </summary>
public Bitmap Gradient = new Bitmap(1, 1);
/// <summary>
/// 绘制Gradient的颜色块大小,默认8像素
/// </summary>
protected CustomColorType customColorType = CustomColorType.Vertical;
#endregion
#region ==声明事件==
/// <summary>
/// 声明选择颜色事件
/// </summary>
[Category("附加"), Description("选择颜色事件"), Browsable(true)]
public event SelectedColor? SelectedColor;
/// <summary>
/// 弹出下拉选择框的事件
/// </summary>
[Category("附加"), Description("弹出下拉选择框的事件"), Browsable(true)]
public event PopupedEvent? DroppedDown;
/// <summary>
/// 点击更多颜色选择的按钮
/// </summary>
[Category("附加"), Description("点击更多颜色选择的按钮"), Browsable(true)]
public event MoreBtnClick? MoreBtnClick;
#endregion
#region ==属性==
private Color borderColor = Color.Black;
/// <summary>
/// 设置边框颜色
/// </summary>
[Category("外观"), Description("设置边框颜色"), Browsable(true)]
public Color BorderColor { get => borderColor; set { borderColor = value; this.Refresh(); } }
/// <summary>
/// 颜色选择器样式
/// </summary>
[Category("外观"), Description("设置弹出颜色选择器的样式\r\ndddd"), Browsable(true)]
public DisplayType DisplayType { get => displayType;
set {
displayType = value;
if (displayType == DisplayType.HightColor) colorValue = new(null, null); // 当转到高亮标记时,需要清空所有的颜色
else colorValue = new(colorValue.Color); // 转化到其他,只需要初始化颜色即可,颜色值可以存在
this.Refresh();
}
}
/// <summary>
/// 设置 或 获取颜色值
/// </summary>
[Browsable(false)] // 不显示在属性面板
public ColorValue ColorValue { get => colorValue; set { colorValue = value; this.Refresh(); } }
/// <summary>
/// 设置 或 获取 选中颜色
/// </summary>
[Category("数据"), Description("设置默认选中颜色"), Browsable(true)]
public Color Value { get => ColorValue.Color;
set{
ColorValue.Color = value;
this.Refresh();
}
}
[Category("数据"), Description("设置自定义颜色时显示的方式"), Browsable(true)]
public CustomColorType CustomColorType
{
get => customColorType;
set =>customColorType = value;
}
/// <summary>
/// 设置 或 获取 选中颜色
/// </summary>
[Category("其他"), Description("在“自定义颜色选择”中允许按回车确认选择颜色(在颜色编辑状态下回车也会返回结果)"), Browsable(true)]
public bool Confirm { set; get; } = true;
#endregion
#region ===构造函数与初始化===
public ColorPicker()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
Init();
CreateImage(); // 可能占用时间,创建一个线程来计算
}
protected void Init()
{
// 初始化 两个区域
this.ColorBtnRect = new Rectangle(this.Width - this.Height, 0, this.Height, this.Height);
this.ColorRect = new Rectangle(0, 0, this.Width - this.Height, this.Height);
}
private void ColorPicker_Load(object sender, EventArgs e)
{
//if (this.displayType == DisplayType.ThemeColor)
//{
// this.colorValue.Color = Color.Empty;
// this.colorValue.Value = "auto";
//}
}
#endregion
#region ===私有方法===
/// <summary>
/// 创建弹出层
/// </summary>
private void CreatePopup()
{
if (Popup == null || Popup.IsDisposed)
{
Popup = new Popup(this);
Point point = this.PointToScreen(new Point(0, this.Height)); // 计算出当前控件距离屏幕的位置
Popup.Location = point;
//this.Parent.Controls.Add(Popup); // 必须等初始化完成后才能添加到父控件
this.ParentForm.MouseClick += ParentForm_MouseClick;
this.ParentForm.Move += ParentForm_Move;
this.ParentForm.SizeChanged += ParentForm_SizeChanged;
}
}
/// <summary>
/// 创建自定义颜色选择的 渐变色图片
/// </summary>
private void CreateImage()
{
//await Task.Run(() => { Gradient = CustomColor.GetColorBrightness(ColorTranslator.FromHtml("#4ad435"),200); }); // 可能占用时间,创建一个线程来计算
//this.Refresh();
}
/// <summary>
/// 主窗口移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void ParentForm_SizeChanged(object? sender, EventArgs e)
{
if (!(this.Popup == null || this.Popup.IsDisposed))
{
Popup.Dispose();
}
}
/// <summary>
/// 窗口移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private void ParentForm_Move(object? sender, EventArgs e)
{
if (Popup != null)
{
Popup.Dispose();
}
}
/// <summary>
/// 定义父窗口鼠标点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ParentForm_MouseClick(object? sender, MouseEventArgs e)
{
// 这里存在问题,点击到不接受焦点的对象,则无法进入此函数
if (!(this.Popup == null || this.Popup.IsDisposed)) // 弹出窗口存在
{
Rectangle rect = new Rectangle(this.Location, this.Size);
if (this.Popup.Visible == true && !rect.Contains(e.Location))
{
this.Popup.Dispose(); // 每次的关闭都是释放资源,需要的时候重新加载
}
}
}
/// <summary>
/// 获取弹出层的位置坐标点
/// </summary>
/// <returns></returns>
private Point GetPopupLocation()
{
if (Popup == null) return Point.Empty;
Point point = this.PointToScreen(new Point(0, this.Height)); // 计算出当前控件距离屏幕的位置
if (point.Y + this.Popup.Height > Screen.PrimaryScreen.WorkingArea.Bottom) // 底边超出了任务栏顶部的位置
{
point.Y = point.Y - this.Height - this.Popup.Height;
}
if (point.X + this.Popup.Width > Screen.PrimaryScreen.WorkingArea.Right) // 底边超出了右边的位置
{
point.X = point.X - (this.Popup.Width - this.Width);
}
return point;
}
#endregion
#region ==自绘控件==
protected override void OnPaint(PaintEventArgs e)
{
DrawBut(e.Graphics);
}
/// <summary>
/// 画按钮边框
/// </summary>
/// <param name="g"></param>
protected virtual void DrawBut(Graphics g)
{
using (Pen pen = new Pen(Color.Red))
{
g.DrawRectangle(Pens.Gray, this.ColorBtnRect); // 画按钮部分边框
using (Brush brush = new SolidBrush(this.ForeColor))
{
float val = MoveRect.IsEmpty ? 0.5f : 0.6f;
g.FillPath(brush, DrawPath.DrawInvertedTriangle(this.ColorBtnRect.Scale(val))); // 画 按钮内部三角形
}
// 判断是否存在颜色
if (this.ColorValue.Color.IsEmpty)
{
if (this.DisplayType == DisplayType.ThemeColor)
{
Rectangle rect = this.ColorRect.Scale(-3);
rect.Width = rect.Height;
g.FillRectangle(Brushes.Black, rect); // 画 自动颜色 黑色方块
Rectangle tRect = this.ColorRect.Scale(-3);
tRect.X = rect.Right + rect.X; // 文字区域X坐标计算
tRect.Width = this.ColorRect.Width - tRect.X - rect.X; // 计算文字区域宽度
SizeF sizeF = g.MeasureString("自动", new Font("宋体", tRect.Height / 2));
if (sizeF.Width < tRect.Width)
{
StringFormat sf = new StringFormat() { LineAlignment = StringAlignment.Center, FormatFlags = StringFormatFlags.LineLimit };
g.DrawString("自动", new Font("宋体", tRect.Height / 2), Brushes.Black, tRect, sf); // 绘制文字
}
}
else if (this.DisplayType == DisplayType.HightColor)
{
Rectangle rect = this.ColorRect.Scale(-3);
rect.Width = rect.Height;
g.FillRectangle(Brushes.White, rect); // 画 自动颜色 黑色方块
g.DrawLine(Pens.Red, rect.X, rect.Bottom, rect.Right, rect.Y); // 填充无颜色图形框中斜线
g.DrawRectangle(Pens.Gray, rect);
Rectangle tRect = this.ColorRect.Scale(-3);
tRect.X = rect.Right + rect.X; // 文字区域X坐标计算
tRect.Width = this.ColorRect.Width - tRect.X - rect.X; // 计算文字区域宽度
SizeF sizeF = g.MeasureString("无", new Font("宋体", tRect.Height / 2));
if (sizeF.Width < tRect.Width)
{
StringFormat sf = new StringFormat() { LineAlignment = StringAlignment.Center, FormatFlags = StringFormatFlags.LineLimit };
g.DrawString("无", new Font("宋体", tRect.Height / 2), Brushes.Black, tRect, sf); // 绘制文字
}
}
}
else
{
using (Brush brush = new SolidBrush(this.ColorValue.Color))
{
g.FillRectangle(brush, this.ColorRect); // 画颜色选择部分
}
}
g.DrawRectangle(pen, this.DisplayRectangle.Shifting(0, 0, -1, -1)); // 画 整个的边框
}
}
#endregion
#region ===处理鼠标相关===
/// <summary>
/// 定义一个鼠标经过的项区域【多定义一个变量,是由于this.ColorBtnRect不能设置为空】
/// </summary>
private Rectangle MoveRect = new Rectangle();
/// <summary>
/// 光标移动
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
if (!MoveRect.IsEmpty && this.MoveRect.Contains(e.Location)) return;
if (this.ColorBtnRect.Contains(e.Location))
{
this.MoveRect = this.ColorBtnRect;
}
else
{
this.MoveRect = Rectangle.Empty;
}
this.Refresh();
}
/// <summary>
/// 光标点击
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(MouseEventArgs e)
{
Stopwatch stopwatch = Stopwatch.StartNew();
if (e.Button != MouseButtons.Left) return;
CreatePopup(); // 只有在弹出的时候在根据 属性值创建对象
if (Popup != null)
{
Popup.TopLevel = true;
Popup.Location = GetPopupLocation();
Popup.Visible = !Popup.Visible;
if (this.DroppedDown != null) DroppedDown(this); // 添加事件
Debug.WriteLine("加载时长:"+stopwatch.ElapsedMilliseconds);
}
}
/// <summary>
/// 光标离开
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
// 鼠标离开了,恢复原本的显示
this.MoveRect = Rectangle.Empty;
this.Refresh();
}
#endregion
#region ==重写其他事件==
/// <summary>
/// 当控件大小改变时
/// </summary>
/// <param name="e"></param>
protected override void OnSizeChanged(EventArgs e)
{
//base.OnSizeChanged(e);
Init();
this.Refresh();
}
/// <summary>
/// 失去焦点
/// </summary>
/// <param name="e"></param>
protected override void OnLostFocus(EventArgs e)
{
if (!(this.Popup == null || this.Popup.IsDisposed)) // 窗口存在
{
if (this.Popup.Focused == false) // 弹出层没有焦点,且
{
if (this.displayType != DisplayType.CustomColor) // 【自定义颜色】比较特殊,需要拥有焦点的。因此当颜色选择器失去焦点他不能隐藏
{
this.Popup.Dispose(); // 每次的关闭都是释放资源,需要的时候重新加载
}
else
{
if (this.Popup.ContainsFocus!=true)
{
this.Popup.Dispose(); // 每次的关闭都是释放资源,需要的时候重新加载
}
}
}
}
}
#endregion
#region ==弹出层传递通知==
/// <summary>
/// 选择颜色事件,方便弹出层调用
/// </summary>
internal void SelectedColorEvent()
{
if (this.SelectedColor!=null)
{
SelectedColor(this, this.colorValue.Color);
}
}
/// <summary>
/// 点击更多颜色选择的按钮事件,方便弹出层调用
/// </summary>
internal void MoreBtnClickEvent()
{
if (this.MoreBtnClick != null)
{
MoreBtnClick(this);
}
}
#endregion
}
2. ColorPlateBase类
internal abstract class ColorPlateBase
{
/// <summary>
/// 绘图的窗口
/// </summary>
protected Popup Popup;
#region ==属性==
/// <summary>
/// 颜色的Html值
/// </summary>
private List<string> colorHtml = new List<string>();
/// <summary>
/// 颜色的Html值
/// </summary>
public List<string> ColorHtml {
get { return colorHtml; }
protected set { colorHtml = value; }
}
/// <summary>
/// 对应的颜色名称
/// </summary>
private List<string> colorName = new List<string>();
/// <summary>
/// 对应的颜色名称
/// </summary>
public List<string> ColorName
{
get { return colorName; }
protected set { colorName = value; }
}
/// <summary>
/// 绘制颜色块的范围
/// </summary>
private List<Rectangle> drawColorRects = new List<Rectangle>();
/// <summary>
/// 绘制颜色块的范围
/// </summary>
public List<Rectangle> DrawColorRects
{
get { return drawColorRects; }
protected set { drawColorRects = value; }
}
#endregion
#region ==字段==
/// <summary>
/// 弹出层默认大小
/// </summary>
public Size DefaultSize;
/// <summary>
/// 准备选中的颜色块
/// </summary>
public Rectangle SelectRect = Rectangle.Empty;
/// <summary>
/// 已选中的颜色块
/// </summary>
public Rectangle SelectedRect = Rectangle.Empty;
/// <summary>
/// 跳转按钮区域
/// </summary>
public Rectangle BtnRect = Rectangle.Empty;
#endregion
/// <summary>
/// 颜色面板基类
/// </summary>
/// <param name="popup">颜色面板弹出层对象</param>
/// <param name="size">弹出层默认大小</param>
public ColorPlateBase(Popup popup,Size size)
{
this.Popup = popup;
DefaultSize = size;
popup.Size = DefaultSize;
}
/// <summary>
/// 绘制界面
/// </summary>
/// <param name="g"></param>
public abstract void Paint(PaintEventArgs e);
/// <summary>
/// 初始化计算画图区间
/// </summary>
public abstract void InitCalculate();
/// <summary>
/// 获取颜色值
/// </summary>
/// <param name="index">colorHtml对应索引的值</param>
/// <returns></returns>
public abstract ColorValue GetColorValue(int index);
}
3. Popup类
internal class Popup : Form
{
#region ===私有成员===
/// <summary>
/// 当前临时跳转过来的
/// </summary>
private DisplayType nowDisplayType;
/// <summary>
/// 颜色选择基类
/// </summary>
private ColorPlateBase ColorPlateBase;
/// <summary>
/// 绑定的颜色选择器
/// </summary>
internal ColorPicker ColorPicker;
#endregion
#region ===重写字段(不激活窗口)===
/// <summary>
/// 不抢焦点,非活动窗口【但就不能通过失去焦点而消失】
/// <para>直接通过重载以下ShowWithoutActivation 属性(默认为false)为true 来快速实现显示窗口时不将其激活</para>
/// </summary>
protected override bool ShowWithoutActivation => true;
#endregion
#region ===构造函数及初始化===
/// <summary>
/// 构造函数
/// </summary>
/// <param name="colorPicker">颜色选择器</param>
/// <exception cref="ArgumentException"></exception>
public Popup(ColorPicker colorPicker)
{
InitializeComponent();
this.nowDisplayType = colorPicker.DisplayType;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.ColorPicker = colorPicker;
this.Visible = false;
switch (this.ColorPicker.DisplayType)
{
case DisplayType.HightColor:
ColorPlateBase = new HeightColor(this);
break;
case DisplayType.ThemeColor:
ColorPlateBase = new ThemeColor(this);
break;
case DisplayType.CommonColor:
ColorPlateBase = new CommonColor(this);
break;
case DisplayType.CustomColor:
ColorPlateBase = new CustomColor(this);
break;
default:
throw new ArgumentException("ColorPicker 没有这个值");
}
CalculateDefaultSelected();
}
private void InitializeComponent()
{
SuspendLayout();
//
// Popup
//
AutoValidate = AutoValidate.Disable;
ClientSize = new Size(150, 150);
ControlBox = false;
DoubleBuffered = true;
FormBorderStyle = FormBorderStyle.None;
MaximizeBox = false;
MdiChildrenMinimizedAnchorBottom = false;
MinimizeBox = false;
Name = "Popup";
ShowIcon = false;
ShowInTaskbar = false;
StartPosition = FormStartPosition.Manual;
ResumeLayout(false);
}
/// <summary>
/// 计算默认选择区域
/// </summary>
private void CalculateDefaultSelected()
{
for (int i = 0; i < this.ColorPlateBase.ColorHtml.Count; i++)
{
if (this.ColorPlateBase.ColorHtml[i] == ColorTranslator.ToHtml(this.ColorPicker.Value).Replace("#",""))
{
if (this.ColorPlateBase.DrawColorRects.Count > i)
{
this.ColorPlateBase.SelectedRect = this.ColorPlateBase.DrawColorRects[i];
}
return;
}
}
}
#endregion
#region ===重绘===
/// <summary>
/// 重绘
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
ColorPlateBase?.Paint(e); // 显示颜色面板的类型
e.Graphics.DrawRectangle(Pens.Gray, this.ClientRectangle.Shifting(0, 0, -1, -1)); // 画边框
DrawSelect(e); // 画选中部分
}
/// <summary>
/// 应当在画完全部内容后调用
/// </summary>
/// <param name="e"></param>
protected virtual void DrawSelect(PaintEventArgs e)
{
// 画选中框
if (!this.ColorPlateBase.SelectRect.IsEmpty)
{
using (var pen = new Pen(Color.Black))
{
pen.Width = 2f;
Rectangle rect = this.ColorPlateBase.SelectRect;
// ============由于右侧和底边画画框是画不到的,因此,调整画选中框===============
if (this.ColorPlateBase.SelectRect.Width == this.Width) rect = rect.Shifting(0, 0, -2, 0); // 如果当前选中的区域宽度与控件宽度一致
if (this.ColorPlateBase.SelectRect.Top == 0) rect = rect.Shifting(0, 2, 0, -2); // 顶部“自动颜色”调整
if (this.ColorPlateBase.SelectRect.Bottom == this.Height) rect = rect.Shifting(0, 0, 0, -2); // 底部“选择其他颜色”调整
e.Graphics.DrawRectangle(pen, rect);
}
}
// 画原有选中区域
if (!this.ColorPlateBase.SelectedRect.IsEmpty)
{
using (var pen = new Pen(Color.Black))
{
pen.Width = 2f;
Rectangle rect = this.ColorPlateBase.SelectedRect;
// ============由于右侧和底边画画框是画不到的,因此,调整画选中框===============
if (this.ColorPlateBase.SelectedRect.Width == this.Width) rect = rect.Shifting(0, 0, -2, 0); // 如果当前选中的区域宽度与控件宽度一致
if (this.ColorPlateBase.SelectedRect.Top == 0) rect = rect.Shifting(0, 2, 0, -2); // 顶部“自动颜色”调整
if (this.ColorPlateBase.SelectedRect.Bottom == this.Height) rect = rect.Shifting(0, 0, 0, -2); // 底部“选择其他颜色”调整
e.Graphics.DrawRectangle(pen, rect);
}
}
}
#endregion
#region ===鼠标相关事件重写===
/// <summary>
/// 光标移除控件范围
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
ColorPlateBase.SelectRect = Rectangle.Empty;
this.Refresh();
}
/// <summary>
/// 鼠标移动
/// </summary>
/// <param name="e"></param>
protected override void OnMouseMove(MouseEventArgs e)
{
if (ColorPlateBase.GetType() == typeof(CustomColor))
{
((CustomColor)ColorPlateBase).MouseMove(e);
return;
}
if (!ColorPlateBase.SelectRect.IsEmpty && ColorPlateBase.SelectRect.Contains(e.Location))
{
return; // 当前光标还没有移除范围
}
// 查找当前 光标移动的位置 是否在那个颜色块中,如果在,则设置选中区域,并刷新返回。
for (int i = 0; i < ColorPlateBase.DrawColorRects.Count; i++)
{
if (ColorPlateBase.DrawColorRects[i].Contains(e.Location))
{
this.ColorPlateBase.SelectRect = ColorPlateBase.DrawColorRects[i];
this.Refresh();
return;
}
}
// 没有找到则设置为空
ColorPlateBase.SelectRect = Rectangle.Empty;
this.Refresh();
}
/// <summary>
/// 鼠标点击
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(MouseEventArgs e)
{
if (ColorPlateBase.GetType() == typeof(CustomColor))
{
((CustomColor)ColorPlateBase).MouseClick(e);
return;
}
for (int i = 0; i < ColorPlateBase.DrawColorRects.Count; i++)
{
if (ColorPlateBase.DrawColorRects[i].Contains(e.Location))
{
if (i == ColorPlateBase.DrawColorRects.Count - 1) // 最后一个选择框
{
if (this.ColorPicker.DisplayType == DisplayType.ThemeColor) // 主题颜色
{
// 【主题颜色的最后一个颜色框是按钮框】这里有个按钮需要单独做逻辑的处理
ColorPlateBase = new CommonColor(this);
this.nowDisplayType = DisplayType.CommonColor;
this.ColorPicker.MoreBtnClickEvent(); // 通知ColorPicker已经点击了选择更多颜色
this.Refresh();
break;
}
else if (this.ColorPicker.DisplayType == DisplayType.CommonColor) // 常用颜色
{
// 【主题颜色的最后一个颜色框是按钮框】这里有个按钮需要单独做逻辑的处理
ColorPlateBase = new CustomColor(this);
this.ColorPicker.MoreBtnClickEvent(); // 通知ColorPicker已经点击了选择更多颜色
this.Refresh();
break;
}
}
this.ColorPicker.ColorValue = ColorPlateBase.GetColorValue(i);
this.ColorPicker.Refresh();
this.Visible = false;
this.ColorPicker.SelectedColorEvent(); // 通知ColorPicker已经选择了颜色
this.Dispose(); // 每次的隐藏都是释放资源
break;
}
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (ColorPlateBase.GetType() == typeof(CustomColor))
{
((CustomColor)ColorPlateBase).MouseUp(e);
return;
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (ColorPlateBase.GetType() == typeof(CustomColor))
{
((CustomColor)ColorPlateBase).MouseDown(e);
return;
}
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (ColorPlateBase.GetType() == typeof(CustomColor))
{
((CustomColor)ColorPlateBase).KeyUp(e);
return;
}
}
#endregion
#region ===窗口大小改变===
protected override void OnSizeChanged(EventArgs e)
{
ColorPlateBase?.InitCalculate();
this.Refresh();
}
#endregion
protected override void OnLostFocus(EventArgs e)
{
if (this.IsDisposed == false)
{
this.Dispose();
}
}
}
4. 代码粘贴貌似有点多了,长度太长了
就不粘贴了,后面我把代码上传了,给下载链接。