前一段时间开发上位机功能需要用到颜色选择器功能,但是C#自带的颜色选择器操作繁琐,而且嵌入到上位机着实不好看,然后我在网上找了很久,发现很少有色轮形式的颜色选择器,所以我上github寻找,发现了一个宝藏——一个非常好看炫酷而且操作简单的的颜色选择器控件,推荐给大家。
【首先贴上github链接:适用于 Windows 窗体的 Cyotek 拾色器控件】

首先贴出效果图看看是不是你想要的:

一、简单使用教程

此处是我使用Cyotek.Windows.Forms.ColorPickers库部分功能的一些经验和思路总结,没有太多深入地去学习,如果有哪位大佬有深入学习使用的话,可以推给我大家一起学习一下。

好了回到正文

1. 简单复习项目创建以及库的安装

(1)点击新建项目->选择Windows窗体应用->点击下一步->填写好项目名称和什么位置->点击创建


(2)打开NuGet 右键:ColorPicker->管理NuGet程序包

在浏览界面输入Cyotek.Windows.Forms.ColorPicker然后直接点击下载

(3)回到Form1.cs[设计],可以看到工具箱里面多了一个选项卡Cyotek Color Picker Controls

2. 实操

控件

控件类型 名称
3个主要控件 ColorWheel
ColorEditor
ColorGrid
5 个实用程序控件 ScreenColorPicker
RgbaColorSlider
HueColorSlider
LightnessColorSlider
SaturationColorSlider
1个管理组件 ColorEditorManager
1个对话框 ColorPickerDialog

(1)把需要用到的控件拖到Form1里面


(2)拖入colorEditorManger控件,然后按F4,绑定上面三个控件

运行效果:


(3)小小拓展一下
将想要的颜色通过串口发送出去
[效果演示]

上面所演示的效果是简单地在串口上位机加上一些颜色选择控件,然后获取到RGB值,并将RGB值放进通信协议里面,最后将数据通过串口发送出去,这样可以实现利用上位机控制RGB灯的颜色的效果。

实现步骤:

  1. 先写好串口上位机,教程可以看我的另一篇推文
  2. 把各种颜色选择控件按照上面的教程拉到窗体里面
  3. 绑定事件(即当颜色发送变化时触发的事件)
    (1)在左下角找到下面这个控件,按下F4

    (2)点击闪电标志,双击ColorChanged旁边的空格子(这样就会自动生成一个函数,当颜色发送改变是会触发这个函数)
  4. 事件代码实现
/**************************************************************************/#region 颜色选择工具拓展private void colorEditorManager1_ColorChanged(object sender, EventArgs e){int r;int g;int b;//将获取到的RGB值进行数据类型转换r = Convert.ToInt32(colorWheel1.Color.R);g = Convert.ToInt32(colorWheel1.Color.G);b = Convert.ToInt32(colorWheel1.Color.B);//将RGB值嵌进通信协议(示例)byte[] temp = new byte[8];temp[0] = 0x66;     temp[1] = 0x04;temp[2] = 0x00;temp[3] = (byte)r;temp[4] = (byte)g;temp[5] = (byte)b;temp[6] = (byte)((0x04 ^ 0x00 ^ (byte)r ^ (byte)g ^ (byte)b) & 0xFF);   //检验temp[7] = 0x99;     richTextBox1.BackColor = Color.FromArgb(r,g,b);     //将颜色显示在richTextBox上面//打印数据richTextBox_ReceiveBox.Text += "发送的RGB值:" + colorWheel1.Color.R + "," + colorWheel1.Color.G + "," + colorWheel1.Color.B + "\n";richTextBox_ReceiveBox.Text += "数据流:";for (int i = 0; i < temp.Length; i++){richTextBox_ReceiveBox.Text += temp[i].ToString("X2") + " ";}richTextBox_ReceiveBox.Text += "\n";Serial_SendData(temp);      //将字节数组通过串口发送}//串口发送函数void Serial_SendData(byte[] buff){               try{serialPort1.Write(buff, 0, buff.Length);}catch{MessageBox.Show("串口通讯错误", "提示");serialPort1.Close();return;}}#endregion/**************************************************************************/

完整的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;namespace ColorPicker
{public partial class Form1 : Form{public Form1(){InitializeComponent();}/**************************************************************************/#region 初始化窗体private void Form1_Load(object sender, EventArgs e) //加载界面程序{try{string[] str = SerialPort.GetPortNames();   //获取连接到电脑的串口号并存进数组comboBox_PortNames.Items.Clear();           //清除串口号下拉框的内容comboBox_PortNames.Items.AddRange(str);     //将串口号添加到下拉框if (str.Length > 0){comboBox_PortNames.SelectedIndex = 0;   //设置ComboBox框的初始值comboBox_BaudRate.SelectedIndex = 7;comboBox_DataBit.SelectedIndex = 3;comboBox_StopBit.SelectedIndex = 1;comboBox_Parity.SelectedIndex = 2;}else{MessageBox.Show("当前无串口连接!");}}catch{MessageBox.Show("无串口设备!/r/n请检查是否连接设备!/r/n请检查设备驱动!");}}#endregion/**************************************************************************//**************************************************************************/#region 搜索串口(与初始化函数一样)private void button_Serach_Click(object sender, EventArgs e){try{string[] str = SerialPort.GetPortNames();comboBox_PortNames.Items.Clear();comboBox_PortNames.Items.AddRange(str);if (str.Length > 0){comboBox_PortNames.SelectedIndex = 0;comboBox_BaudRate.SelectedIndex = 7;comboBox_DataBit.SelectedIndex = 3;comboBox_StopBit.SelectedIndex = 1;comboBox_Parity.SelectedIndex = 2;}else{MessageBox.Show("当前无串口连接!");}}catch{MessageBox.Show("无串口设备!/r/n请检查是否连接设备!/r/n请检查设备驱动!");}}#endregion/**************************************************************************//**************************************************************************/#region 打开串口private void button_OpenOrClose_Click(object sender, EventArgs e){if (!serialPort1.IsOpen){if (comboBox_PortNames.SelectedItem == null){MessageBox.Show("请选择正确的串口", "提示");return;}//设置串口参数serialPort1.PortName = comboBox_PortNames.Text.ToString();  //serialPort1是serialPort组件的Name serialPort1.BaudRate = Convert.ToInt32(comboBox_BaudRate.SelectedItem.ToString());serialPort1.DataBits = Convert.ToInt32(comboBox_DataBit.SelectedItem.ToString());//设置停止位if (comboBox_StopBit.Text == "One"){serialPort1.StopBits = StopBits.One;}else if (comboBox_StopBit.Text == "Two"){serialPort1.StopBits = StopBits.Two;}else if (comboBox_StopBit.Text == "OnePointFive"){serialPort1.StopBits = StopBits.OnePointFive;}else if (comboBox_StopBit.Text == "None"){serialPort1.StopBits = StopBits.None;}//设置奇偶校验位if (comboBox_Parity.Text == "Odd"){serialPort1.Parity = Parity.Odd;}else if (comboBox_Parity.Text == "Even"){serialPort1.Parity = Parity.Even;}else if (comboBox_Parity.Text == "None"){serialPort1.Parity = Parity.None;}try{//禁止操作组件comboBox_PortNames.Enabled = false;comboBox_BaudRate.Enabled = false;comboBox_DataBit.Enabled = false;comboBox_StopBit.Enabled = false;comboBox_Parity.Enabled = false;button_Serach.Enabled = false;serialPort1.Open(); //设置完参数后打开串口button_OpenOrClose.Text = "Close";  //更改Open按钮文本内容}catch{MessageBox.Show("串口打开失败!");}//事件绑定方法,在DataReceivedserialPort1.DataReceived += new SerialDataReceivedEventHandler(SerialDataReceive);  //打开串口后绑定数据接收}else if (button_OpenOrClose.Text == "Close"){try{//允许操作组件comboBox_PortNames.Enabled = true;comboBox_BaudRate.Enabled = true;comboBox_DataBit.Enabled = true;comboBox_StopBit.Enabled = true;comboBox_Parity.Enabled = true;button_Serach.Enabled = true;serialPort1.DiscardInBuffer();  //清除缓冲区的数据serialPort1.Close();button_OpenOrClose.Text = "Open";   //更改Close按钮文本内容}catch{MessageBox.Show("串口打开失败!");}}}#endregion/**************************************************************************//**************************************************************************/#region 接收串口数据/*开辟缓存区 根据具体协议内容获取一帧数据进行接收中断处理*///变量List<byte> sp_buffer = new List<byte>(4096);    //串口缓存区int sp_buffer_max = 4096;   //串口缓存区最大缓存字节数private void SerialDataReceive(object sender, SerialDataReceivedEventArgs e){if (serialPort1.IsOpen == false){serialPort1.Close();return;}int Byte_len = serialPort1.BytesToRead; //读取缓存的数据长度byte[] Rc_byte = new byte[Byte_len];serialPort1.Read(Rc_byte, 0, Byte_len);   //将缓存数据存储进字节数组里面if (sp_buffer.Count > sp_buffer_max)    //缓存超过字节数 先丢弃前面的字节  sp_buffer.RemoveRange(0, sp_buffer_max); //丢弃前面的字节0到sp_buffer_maxsp_buffer.AddRange(Rc_byte);    //存入缓存区byte[] ruffer = new byte[9192]; //用来存放缓冲区的数据流//对数据流进行筛选,缓冲区每一组数据个数大于4则为我们想要的数据流if (sp_buffer.Count > 4){sp_buffer.CopyTo(0, ruffer, 0, sp_buffer.Count);Task.Run(() => printf_data(ruffer, sp_buffer.Count, 1));  //打印数据流}}#endregion/**************************************************************************//**************************************************************************/#region 打印数据流void printf_data(byte[] Frame, int Length, int T_R)   //打印串口数据{Int16 i_len;StringBuilder s = new StringBuilder();if (T_R == 0)s.Append("发送:");elses.Append("接收:");for (i_len = 0; i_len < Length; i_len++)       //打印字符串{s.Append(Frame[i_len].ToString("X2"));s.Append(" ");}s.Append("[" + DateTime.Now.ToString("HH:mm:ss fff") + "]");s.Append("\r\n");string str_show = s.ToString();MethodInvoker mi = new MethodInvoker(() =>{if (richTextBox_ReceiveBox.Lines.Count() > 20)richTextBox_ReceiveBox.Clear();richTextBox_ReceiveBox.AppendText(str_show);});BeginInvoke(mi);/*textBox_com_data.Focus(); //获取焦点textBox_com_data.Select(textBox_com_data.TextLength, 0);//光标textBox_com_data.ScrollToCaret(); //滚动条*/}#endregion/**************************************************************************//**************************************************************************/#region 发送数据private void button_Send_Click(object sender, EventArgs e){if (serialPort1.IsOpen){string[] sendbuff = richTextBox_send.Text.Split();  //分割输入的字符串,判断有多少个字节需要发送int Buff_Len = sendbuff.Length;byte[] buff = new byte[Buff_Len];for (int i = 0; i < sendbuff.Length; i++){buff[i] = byte.Parse(sendbuff[i], System.Globalization.NumberStyles.HexNumber); //格式化字符串为十六进制数值}try{serialPort1.Write(buff, 0, buff.Length);    //写数据Task.Run(() => printf_data(buff, Buff_Len, 0));}catch{MessageBox.Show("发送失败!!");}}else{MessageBox.Show("串口未打开!");}}#endregion/**************************************************************************//**************************************************************************/#region 清除输出框private void Clear_Click(object sender, EventArgs e){richTextBox_ReceiveBox.Clear();     //清楚数据接收框数据}#endregion/**************************************************************************//**************************************************************************/#region 颜色选择工具拓展private void colorEditorManager1_ColorChanged(object sender, EventArgs e){int r;int g;int b;r = Convert.ToInt32(colorWheel1.Color.R);g = Convert.ToInt32(colorWheel1.Color.G);b = Convert.ToInt32(colorWheel1.Color.B);//将RGB值嵌进通信协议(示例)byte[] temp = new byte[8];temp[0] = 0x66;     temp[1] = 0x04;temp[2] = 0x00;temp[3] = (byte)r;temp[4] = (byte)g;temp[5] = (byte)b;temp[6] = (byte)((0x04 ^ 0x00 ^ (byte)r ^ (byte)g ^ (byte)b) & 0xFF);   //检验temp[7] = 0x99;     richTextBox1.BackColor = Color.FromArgb(r,g,b);     //将颜色显示在richTextBox上面//打印数据richTextBox_ReceiveBox.Text += "发送的RGB值:" + colorWheel1.Color.R + "," + colorWheel1.Color.G + "," + colorWheel1.Color.B + "\n";richTextBox_ReceiveBox.Text += "数据流:";for (int i = 0; i < temp.Length; i++){richTextBox_ReceiveBox.Text += temp[i].ToString("X2") + " ";}richTextBox_ReceiveBox.Text += "\n";Serial_SendData(temp);      //将字节数组通过串口发送}//串口发送函数void Serial_SendData(byte[] buff){               try{serialPort1.Write(buff, 0, buff.Length);}catch{MessageBox.Show("串口通讯错误", "提示");serialPort1.Close();return;}}#endregion/**************************************************************************/}
}

二、官方介绍

Cyotek.Windows.Forms.ColorPickers库包含一系列自定义控件和实用程序类,适用于使用颜色的 Windows 窗体应用程序。控件可用于通过 HSL 进行颜色选择ColorWheel,ColorGrid 具有许多自定义选项,ColorEditor用于通过 RGB 或 HSL 输入颜色,以及ScreenColorPicker用于从正在运行的应用程序中捕获颜色。

调色板可以以多种不同的格式加载和保存,包括 Adob​​e PhotoShop 色板文件、JASC 调色板、Gimp 调色板等(请参阅下面的调色板和外部调色板文件)。

有关这些控件的更多信息,请参阅cyotek.com 上带有标签的文章。colorpicker

(1)获取Lib

获取库的最简单方法是通过NuGet
Install-Package Cyotek.Windows.Forms.ColorPicker
如果您不使用 NuGet,可以从GitHub 发布页面获取预编译的二进制文件。

当然,您可以随时获取源代码并自己构建!

(2)控件

控件类型 名称
3个主要控件 ColorWheel
ColorEditor
ColorGrid
5 个实用程序控件 ScreenColorPicker
RgbaColorSlider
HueColorSlider
LightnessColorSlider
SaturationColorSlider
1个管理组件 ColorEditorManager
1个对话框 ColorPickerDialog

1. 颜色网格控件 ColorGrid Controls


此控件显示颜色网格,并支持主调色板和自定义调色板。有几个属性可用于配置控件的显示,也有一些行为选项,例如内置的颜色编辑和支持自动添加不在主调色板中的新颜色。

2.色轮控制 ColorWheel


此控件显示 RGB 颜色的径向轮,并允许从轮中的任何点进行选择。ShowAngleArrow、ShowCenterLines 和ShowSaturationRing属性可用于显示有用的装饰,而Lightness和Alpha属性可用于组成最终颜色,但不能在轮子上直接编辑。
SecondaryColors和SecondarySelectionSize属性允许您在轮盘上显示其他颜色例如用于显示关系。

3.颜色滑块控件 ColorSlider


一组控件(从单个基类继承),允许通过彩色条选择值。与 TrackBar控件类似,您有几个选项可用于指定拖动手柄的位置和条形方向。您还可以自定义填充和轮廓颜色,或将其完全替换为自定义图像。

4.颜色编辑器控件 ColorEditor


此控件允许通过标准界面编辑 RGB 或 HSL 颜色。您还可以通过 6 或 8 个字符的十六进制表示法输入颜色,或从命名的 Web 和系统颜色中进行选择。
可以通过 ShowAlphaChannel和PreserveAlphaChannel属性配置 alpha 通道的使用。ShowHex、ShowHsl和ShowRgb属性可用于显示或隐藏编辑器组件或者,NubSizeNubColor和NubOutlineColor 属性可用于自定义滑块的外观。

5.ScreenColorPicker 控件


此控件允许用户从屏幕上显示的任何像素中选择颜色。用户可以通过单击并拖动控件来触发操作,也可以通过该CaptureMouse方法以编程方式完成,允许通过其他操作(例如热键)触发选择。该Zoom属性可用于设置预览的网格大小。

6.颜色选择器对话框窗体 ColorPickerDialog


此表单将前面的控件放在一个随时可用的对话框中。
通过该属性支持自定义颜色CustomColors,用户还可以将外部调色板文件加载或保存到其中。您可以使用ShowLoadShowSave属性来启用或禁用此功能,并使用CustomColorsLoadingCustomColorsSaving事件来覆盖内置行为并提供您自己的逻辑。

4.颜色编辑器管理器 ColorEditorManager


这是一个非 GUI 组件,您可以将其拖放到表单上,并绑定到此库中的其他控件。当Color 一个控件的属性发生变化时,它会反映在其他控件中,而无需抬起手指。如果您从多个控件创建复合显示,这很有用。

调色板和外部调色板文件

ColorGrid控件有CustomColors和Colors属性能够返回一个颜色集合。这两个属性使开发人员可以更轻松地保持单独的主调色板,同时具有自定义颜色的灵活性,尽管它确实使控件的内部逻辑有点复杂!如果您尝试将控件设置为当前未定义的值,网格将自动填充自定义颜色。
除了手动填充颜色集合实例外,您还可以加载外部调色板文件。支持以下调色板格式:

Adobe 颜色表 (.act)
Adobe PhotoShop 色板 (
.aco)
GIMP (.gpl)
豪华油漆 (
.bbm; .lbm) [只读]
JASC (
.pal)
Paint.NET (.txt)
原始 RGB 三元组 (
.pal)
除了 ILBM 图像格式之外,所有其他格式都可以导出和导入。

通过添加实现IPaletteSerializer. (或任何使用静态方法的 ColorPickerDialog自定义代码 PaletteSerializer)将通过反射自动检测并提供自定义调色板。

键盘支持

所有 GUI 组件, ScreenColorPicker包括完整的键盘/焦点支持除外。许多控件支持SmallChange和LargeChange影响导航键处理方式的属性。虽然在这种情况下ColorWheel它并不是真正的奖励…但这就是ColorEditor控制最适合的!

好看炫酷又好用的C#颜色选择器相关推荐

  1. web设置网页背景为好看炫酷的渐变色样式

    效果图: 源代码: <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...

  2. 制作超级好看炫酷的一个桌面

    话不多说先上图: 左边导航栏: 顶部导航栏: 鼠标放到左边时候的电脑桌面:不是壁纸!就是电脑全屏截图! 干干净净的桌面而且是动态的,图片展现不出来,桌面上什么都没有,有用的应用或常用的文件已经网站在隐 ...

  3. python3d相册源代码_js和CSS3炫酷3D相册展示

    js和CSS3炫酷3D相册展示 *{margin:0;padding:0;} body{background:url(img/bg.jpg);width:100%;height:100%;overfl ...

  4. WPS如何并排放置两张图片_「WPS办公助手」想做出高级又好看的 PPT,这个炫酷的功能你可别错过...

    如果有人问我,有没有方法可以让 PPT 变得好看且更高级,我第一时间想到的就是它. 话不多说,直接上图: 这起源于keynote的"神奇移动",它可以使PPT里的元素实现非常炫酷的 ...

  5. 苹果cmsv10黑色自适应好看的炫酷简约带会员中心模板

    模板名称:苹果cmsv10黑色自适应好看的炫酷简约带会员中心模板 模板程序:苹果cmsv10 模板类型:自适应模板 空间支持:php5.6+mysql 模板颜色:黑色 模板来源:来自网络收集 下载方式 ...

  6. 好看又炫酷的网页特效例子收集

    1.鼠标点击系列 1.1鼠标点击弹出爱心 <!DOCTYPE html> <html lang="en"> <head><meta cha ...

  7. 好看的html登录遮罩提示加载中,jQuery炫酷页面预加载Loading特效插件

    fakeLoader.js是一款轻量级的 jQuery 炫酷页面预加载Loading特效插件.它能帮助我们创建一个全屏遮罩效果的旋转loading效果来模拟页面预加载过程. Bower安装 bower ...

  8. python表白源代码加音乐_python炫酷烟花表白源代码

    天天敲代码的朋友,有没有想过代码也可以变得很酷炫又浪漫?今天就教大家用Python模拟出绽放的烟花,工作之余也可以随时让程序为自己放一场烟花秀. python炫酷烟花表白源代码 这个有趣的小项目并不复 ...

  9. 就是这么牛逼,利用Python绘制炫酷专业插图就是这么简单

    强烈推荐 Python 的绘图模块 matplotlib: python plotting .画出来的图真的是高端大气上档次,低调奢华有内涵~ 适用于从 2D 到 3D,从标量到矢量的各种绘图.能够保 ...

最新文章

  1. Moodle安全漏洞如何启动远程代码执行?
  2. 【简报】创建线框结构的PDF格式草图表
  3. Python学习系列day5-python基础
  4. centos6.8安装oracle12C 详细步骤讲解
  5. 揭开网络编程常见API的面纱【下】
  6. 实际工程中加快 Java 代码编写的小提示
  7. epoll的一个使用例子
  8. 今年要如何准备?想去阿里/美团/头条做机器学习工程师
  9. 1011 A+B和C
  10. 10月17号PC端云音乐项目总结
  11. Ubuntu的一些高(sao)效(cao)率(zuo)工具
  12. [区间dp]涂色 洛谷P4170
  13. 行云创新:车云一体化平台,实现软件定义汽车
  14. 跟我学Python图像处理丨关于图像金字塔的图像向下取样和向上取样
  15. [开源]圆形FOC无刷驱动Baize_foc
  16. E站账号cookie分享_关于亚马逊账买手账号的分类
  17. 中国汉字书法的回溯感和信息熵
  18. UserWarning: The given NumPy array is not writable, and PyTorch does not support non-writable tenso
  19. 武警二路擒敌拳16式——第一式动作分解
  20. Python爬虫:scrapy辅助功能实用函数

热门文章

  1. 51单片机汽车胎压大气气压测量仪仿真设计_数码管显示
  2. 编译原理php,PHP8.0新特性:JIT即时编译
  3. 六年级有甲乙丙三个班c语言,黄瓜怎么做好吃C语言逻辑推理例题(附答案)吝啬的近义词...
  4. 网曝广州某HR干扰离职员工找工作,在HR群里称“如遇该员工,欢迎找我背调”!...
  5. uniApp页面钩子函数
  6. 读书笔记--GO语言精进之路--01熟知GO语言的一切
  7. (二)python编辑PDF文件:pdfplumber库操作
  8. 基于SOA的区域卫生信息平台案例分析(转)
  9. 计算机二级新题access,2018年计算机二级考试Access试题及答案二
  10. 专访智链ChainNova CTO谢文杰:区块链容器化与水平扩展实践