这一篇介绍如何写一个单色和渐变色的颜色选择下拉框(ComboBox)控件。有些功能中,需要用户自定义选颜色时,一般只需调用ColorDialog颜色选择控件就可以了,但如果为了更贴近ArcGIS的操作风格,且需要使用渐变颜色时,ColorDialog可能就不能满足需求了。
熟悉ArcGIS操作的朋友可能记得,在图层、要素等的颜色设置时用到颜色下拉框选择颜色,其中就有选渐变颜色的下拉框,如下图。在某些二次开发项目中可能会遇到类似的颜色选择需求,希望这里的介绍对需要的朋友能起到一点帮助作用。
TIN模型按高程选择渐变颜色
1.单色颜色下拉框
其思路就是往ComboBox中添加记录颜色值的项(Item),再根据该颜色值重绘ComboBox对应项的矩形区域,达到直接显示的效果。
具体步骤如下:
先在项目下添加一个新的UserControl控件,再拖一个ComboBox控件到UserControl上,将ComboBox的Dock属性设为Fill,再调整UserControl的大小,使其与刚好完全位于ComboBox下,最后关键的一步就是加入代码。下面贴上代码,具体的解释见代码注释,效果如下图:
单一色效果
using System.Windows.Forms;
using System.Drawing;
using System;
namespace WindowsFormsApplication1
{
/// <summary>
/// 单一颜色选择控件类
/// </summary>
public partial class PureColorComboBox : UserControl
{
private Color _SelectedColor;
/// <summary>
/// 已选择颜色,封装字段
/// </summary>
public Color SelectedColor
{
get { return _SelectedColor; }
set { _SelectedColor = value; }
}
/// <summary>
/// Combobox颜色选择发生变化时激发的事件
/// </summary>
public event EventHandler SelectColorChanged;
//自定义的初始颜色值,有必要时可以指定一些特定的颜色
//private static string[] colorList =
//{
// "AliceBlue","AntiqueWhite","Aqua","Aquamarine","Azure","Beige",
// "Bisque","Black","BlanchedAlmond","Blue","BlueViolet","Brown",
// "BurlyWood","CadetBlue","Chartreuse","Chocolate","Coral",
// "CornflowerBlue","Cornsilk","Crimson","Cyan","DarkBlue","DarkCyan",
// "DarkGoldenrod","DarkGray","DarkGreen","DarkKhaki","DarkMagenta",
// "DarkOliveGreen","DarkOrange","DarkOrchid"
//};
/// <summary>
/// 构造函数
/// </summary>
public PureColorComboBox()
{
InitializeComponent();
AddComponent();
}
/// <summary>
/// 加载各颜色项(Items)
/// </summary>
private void AddComponent()
{
this.comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
//设定ComboBox的高度
this.comboBox1.ItemHeight = 18;
this.comboBox1.BeginUpdate();
this.comboBox1.Items.Clear();
//如要使用自定义颜色初始值时则使用这段代码
//foreach (string oneColor in colorList)
//{
// this.comboBox1.Items.Add(oneColor);
//}
//加载系统所有的颜色,如果使用自定义颜色初始值时则注销下面的代码
Array colors = System.Enum.GetValues(typeof(KnownColor));
for (int i = colors.GetLength(0) - 1; i >= 0; i--)
{
this.comboBox1.Items.Add(colors.GetValue(i).ToString());
}
this.comboBox1.EndUpdate();
}
//在ComboBox的DrawItem事件(绘制事件)中绘制颜色矩形框,每次添加Item时都会触发该事件
//该函数由在ComboBox的属性标签的事件栏下双击DrawItem自动生成
//当然,也可以自己在前面添加
//this.comboBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem);
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
return;
Rectangle rect = e.Bounds; //获取Item矩形框
//获取对应项记录的颜色值
string colorName = comboBox1.Items[e.Index].ToString();
//新建单一色刷子,颜色为对应项记录的值
SolidBrush brush = new SolidBrush(Color.FromName(colorName));
_SelectedColor = brush.Color;
//为美观,可缩小选定项区域1个像素
rect.Inflate(-1, -1);
// 填充颜色
e.Graphics.FillRectangle(brush, rect);
// 用黑色绘制颜色边框
e.Graphics.DrawRectangle(Pens.Black, rect);
}
/// <summary>
/// 在ComboBox选择项改变触发事件中激活颜色传递事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//如果使用该控件的窗体注册了SelectColorChanged事件,则激活
//相当于用SelectColorChanged事件替换了ConboBox的SelectedIndexChanged事件
if (SelectColorChanged != null)
{
SelectColorChanged(this, e);
}
}
}
}
最后,将该颜色控件像使用其他控件一样拖入需要的窗体中,在该控件的SelectColorChanged事件下,通过控件的SelectedColor属性获得选择的颜色值:
//下拉框所选颜色值发生改变时触发的事件
private void colorComboBox1_SelectColorChanged(object sender, EventArgs e)
{
//通过ComboBox的SelectedColor公共字段获取当前选中的值
MessageBox.Show("当前选中的颜色为: "+this.colorComboBox1.SelectedColor.ToString());
}
2.渐变色的颜色下拉框
渐变的颜色下拉框的与单色下拉框的思路是一样的,只是着色方案和初始颜色设定稍微不同,这里只把的代码贴出来,注释较略,其他则可参照上传的具体实例,效果如下:
渐变色颜色下拉框
using System.Windows.Forms;
using System.Drawing;
using System;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
public partial class GradientColorComboBox : UserControl
{
private Color _FromColor;
private Color _ToColor;
public Color FromColor
{
get { return _FromColor; }
set { _FromColor = value; }
}
public Color ToColor
{
get { return _ToColor; }
set { _ToColor = value; }
}
public event EventHandler SelectColorChanged;
//预定义的渐变色
private static string[] colorList =
{
"AliceBlue|AntiqueWhite","Aqua|Aquamarine","Azure|Beige",
"Bisque|Black","BlanchedAlmond|Blue","BlueViolet|Brown",
"BurlyWood|CadetBlue","Chartreuse|Chocolate",
"CornflowerBlue|Cornsilk","Crimson|Cyan","DarkBlue|DarkCyan",
"DarkGoldenrod|DarkGray","DarkGreen|DarkKhaki",
"DarkMagenta|DarkOliveGreen","DarkOrange|DarkOrchid"
};
public GradientColorComboBox()
{
InitializeComponent();
PersonalizeComponent();
}
private void PersonalizeComponent()
{
this.comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
this.comboBox1.ItemHeight = 18;
this.comboBox1.BeginUpdate();
this.comboBox1.Items.Clear();
foreach (string oneColor in colorList)
{
this.comboBox1.Items.Add(oneColor);
}
this.comboBox1.EndUpdate();
}
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
return;
Rectangle rect = e.Bounds;
//读取起始、终止颜色值
string fColorName = comboBox1.Items[e.Index].ToString().Split('|')[0];
string tColorName = comboBox1.Items[e.Index].ToString().Split('|')[1];
_FromColor = Color.FromName(fColorName);
_ToColor = Color.FromName(tColorName);
//选择线性渐变刷子
LinearGradientBrush brush = new LinearGradientBrush(rect, _FromColor, _ToColor, 0, false);
rect.Inflate(-1, -1);
// 填充颜色
e.Graphics.FillRectangle(brush, rect);
// 绘制边框
e.Graphics.DrawRectangle(Pens.Black, rect);
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (SelectColorChanged != null)
{
SelectColorChanged(this, e);
}
}
}
}
同样,将该渐变色控件拖入需要使用窗体中,在该控件的SelectColorChanged事件下,通过控件的FromColor和ToColor属性获得选择的渐变色值:
private void gradientColorComboBox1_SelectColorChanged(object sender, EventArgs e)
{
MessageBox.Show("当前选中的颜色为: " + this.gradientColorComboBox1.FromColor.ToString() + this.gradientColorComboBox1.ToColor.ToString());
}