65.9K
CodeProject 正在变化。 阅读更多。
Home

ColorPicker - 占用空间小的ColorPicker(VB.NET)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (40投票s)

2008 年 10 月 1 日

CPOL

6分钟阅读

viewsIcon

132511

downloadIcon

3779

一个带有吸管和快速样本的RGB/HSB颜色选择控件。

ColorPickerNoRGB.jpg

引言

颜色选择器……难道市面上不是有很多了吗?是的,但它们都没有真正满足我的需求。有一些很酷的,但要么太大,要么太受限。此外,我喜欢挑战。我想要的是能够轻松地从颜色渐变条中选择颜色,并调整亮度和饱和度(HSB)。再次,市面上已经有了,但我想要一个占用空间更小的控件。我不想让控件占用我大部分的表单区域,也不想每次都打开一个单独的对话框。所以,这是我的版本。

库中的控件

  • gColorPicker
  • gEyeDropper
  • gColorComboBox
  • gEnumBox

ColorPicker控件功能

  • 色相(颜色)选择条
  • 饱和度调整条
  • 亮度调整条
  • Alpha(透明度)调整滑块
  • RGB - 红色、绿色和蓝色调整轨迹条(可选)
  • 预定义颜色样本飞出
  • 吸管工具,可从屏幕上任何位置选择颜色

ColorPickerFeatures.jpg

事件

  • Public Event ColorPicked(ByVal sender As Object, _
           ByVal CurrentColor As Color, ByVal ClosestColorName As String)
  • 当颜色条被点击时,此事件将触发。

  • Public Event ColorChanging(ByVal sender As Object, _
           ByVal CurrentColor As Color, ByVal ClosestColorName As String)
  • 当颜色值改变时,此事件将触发。

Init

该类 Implements ISupportInitialize

然后使用下面的代码,在控件初始化期间,可以在 Value Property 中阻止 ColorChanging 事件。

Private Sub BeginInit() Implements ISupportInitialize.BeginInit
    Initializing = True
End Sub

Private Sub EndInit() Implements ISupportInitialize.EndInit
    Initializing = False
End Sub

初始化

构建颜色条并布置控件。这里加载了两个资源。第一个是 HideCursor.cur。这是一个空白光标,用于调整条形选择器时,光标会消失。第二个是 Lizardsml.jpg,用于平铺在颜色条后面,以更好地显示alpha透明度。如果由于某种原因这些资源丢失,它将为每个资源加载一个备份。

控件属性

以下是主要属性列表

  • 当前选择的颜色。

  • HideRGB
  • 显示或隐藏RGB控制框。

  • FlyOut
  • 飞出是在 MouseOver 时打开还是在 Click 时打开?此属性也可在运行时从上下文菜单中获取。

颜色助手

特别感谢Guillaume Leparmentier的出色文章:在.NET中操作颜色 - 第1部分 [^]。为了在RGB和HSB之间转换,我在这里使用了他的一些RGB/HSB助手代码,只做了少量修改。

鼠标事件

跟踪光标是否在条形或alpha指针上。

用于矩形区域

If New Rectangle(ptColor, szColor).Contains(e.Location) Then
    .
    .
    .
End If

用于不规则区域 (GraphicsPath)

If GetAlphaPath(sngXAlpha).IsVisible(e.Location) Then
    .
    .
    .
End If

绘图

包含绘制条形和指针、使选择器无效以及绘制控件的例程。

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(e)

    Dim g As Graphics = e.Graphics

    'Draw Color Value
    g.FillRectangle(New TextureBrush(bmpImg, WrapMode.Tile), ValueDisplay)
    g.FillRectangle(New SolidBrush(Color.FromArgb(CInt(nudAlpha.Value), _
        _Value)), ValueDisplay)

    'Draw a rectangle around the ValueDisplay
    g.DrawRectangle(Pens.DarkGray, ValueDisplay.Location.X - 3, _
        ValueDisplay.Location.Y - 3, ValueDisplay.Width + 5, _
        ValueDisplay.Height + 5)

    'Draw the Alpha Pointer
    g.FillPath(New SolidBrush(AlphaColor), GetAlphaPath(sngXAlpha))
    g.DrawPath(Pens.Blue, GetAlphaPath(sngXAlpha))

    'Draw Hue Color Bar
    g.DrawImage(bmpColorBar, ptColorPaint)
    DrawSelector(g, New Rectangle(ptColor, szColor), _
        sngXColor, panHueSwatch.BackColor)

    'Draw Saturation Color Bar
    Using br As LinearGradientBrush = New LinearGradientBrush _
      (New Rectangle(ptSatPaint.X + 3, ptSatPaint.Y + 3, _
      szSat.Width, szSat.Height), _
      Color.White, CurrColor, LinearGradientMode.Horizontal)
        g.FillRectangle(br, New Rectangle( _
            ptSatPaint.X + 3, ptSatPaint.Y + 3, szSat.Width, szSat.Height))
        g.DrawRectangle(Pens.DarkGray, New Rectangle( _
            ptSatPaint.X, ptSatPaint.Y, szSat.Width + 5, szSat.Height + 5))
    End Using

    'DrawSelector
    DrawSelector(g, New Rectangle(ptSat, szSat), sngXSat, _
        HSBtoColor(nudHue.Value, nudSat.Value / 100, 1))

    'Draw Brightness Color Bar
    g.DrawImage(bmpBrightBar, ptBrightPaint)
    DrawSelector(g, New Rectangle(ptBright, szBright), sngXBright, _
        HSBtoColor(0, 0, nudBright.Value / 100))

End Sub

控制事件

包含颜色选择器控件上控件的事件。

ColorBox

DrawItem 事件,用于接管绘制组合框项目并为每个项目添加颜色样本。

吸管事件

根据 EyeDropper 控件更新样本和颜色值。EyeDropper 具有这两个事件

  • Public Event SelectedColorChanging(ByVal sender As Object, _
        ByVal CurrColor As Color)
  • Public Event SelectedColorChanged(ByVal sender As Object, _
        ByVal CurrColor As Color)

ColorPickerDesigner

ControlDesigner,用于创建SmartTag。设计器操作指南请参见此处:UITypeEditorsDemo[^]。

ColorPickerSmartTag.jpg

吸管

如果你愿意,EyeDropper 按钮 EyeDropperButton.jpg 实际上可以作为一个单独的控件使用。使用dll或添加类,并将 Dropper.cur Cursor.png 作为嵌入资源添加。

点击按钮激活控件并打开缩放窗口。只要鼠标按钮保持按下状态,它就保持激活。释放鼠标按钮将设置选定的颜色。当鼠标在按钮按下的情况下移动时,它会调用 Sub GetScreenShot

GetScreenShot 将确定鼠标位置周围的矩形区域以进行屏幕截图。然后它调用 Graphics 对象的 CopyFromScreen 来获取屏幕该部分的 Bitmap。然后使用 BitmapGetPixel 函数在中心点获取像素的 Color

ZoomWindowType - 设置缩放窗口是显示在原位还是作为随鼠标移动的 Custom Cursor 显示。Custom Cursor 使用了 gCursor[^] 的技术。

ShowSelectedSwatch - 设置缩放窗口是否显示 Selected Color 的样本。

ColorPickerSmartTag.jpg

显示缩放窗口在原位

ColorPickerSmartTag.jpg

显示缩放窗口作为自定义光标

ColorPickerSmartTag.jpg

ZoomLevel

设置ZoomLevel以改变像素在缩放窗口中放大的大小。

ColorPickerSmartTag.jpg

Sub GetScreenShot()

    'The Mouse position is in the middle of the zoom box
    '   Determine the upper right corner point 
    '   of the zoom box from the mouse's position
    Dim scrPt As Point = Control.MousePosition
    scrPt.X = CInt(scrPt.X - bmpScreenShot.Width / 2)
    scrPt.Y = CInt(scrPt.Y - bmpScreenShot.Height / 2)

    'Copy the current piece of the screen to the bmpScreenShot Bitmap
    Using g As Graphics = Graphics.FromImage(bmpScreenShot)
        g.CopyFromScreen(scrPt, New Point(0, 0), bmpScreenShot.Size)
    End Using

    'Determine the color of the pixel in the center of the box
    SelectedColor = bmpScreenShot.GetPixel( _
        CInt(bmpScreenShot.Size.Width / 2), _
        CInt(bmpScreenShot.Size.Height / 2))

    Invalidate()

End Sub

gTrackBar RGB滑块 - 1.3版新增

我将用于RGB调整的Microsoft TrackBars替换为我的gTrackBar [^]。为什么?因为它看起来更好。

将 gColorPicker 放入下拉菜单

为了更小的占用空间,您可以将 gColorPicker 放入下拉菜单中。这里有两种选择。

ToolStripDropDownButton

ToolStripDropDownButton 中托管 gColorPicker:首先声明 gColorPickerToolStripDropDownButton

Private WithEvents gcpToolStripForeColor As ColorPickerLib.gColorPicker = _
    New ColorPickerLib.gColorPicker
Private ReadOnly ToolStripDropDownButton1 As ToolStripDropDownButton = _
    New ToolStripDropDownButton()

然后在表单的Load事件中设置所有内容。

'Customize the gColorPicker
gcpToolStripForeColor.Value = lblTextSample.ForeColor
gcpToolStripForeColor.BackColor = Color.White
'Create a host for the gColorPicker
Dim Host1 As ToolStripControlHost = _
    New ToolStripControlHost(gcpToolStripForeColor)
Host1.AutoSize = False
'Create a dropdown to put the host in
Dim dropDown1 As New ToolStripDropDown()
dropDown1.Items.Add(Host1)
'Customize the DropDownButton
ToolStripDropDownButton1.Text = "ForeColor"
ToolStripDropDownButton1.DisplayStyle = _
    ToolStripItemDisplayStyle.ImageAndText
ToolStripDropDownButton1.Image = _
    MakeColorSquare(gcpToolStripForeColor.Value)
'Add the DropDownButton to the ToolStrip
ToolStrip1.Items.Add(ToolStripDropDownButton1)
'Add the Dropdown to the button
ToolStripDropDownButton1.DropDown = dropDown1

DropDownContainer

我制作了一个 DropDownContainer,用于放置 ColorPicker 或任何控件到 DropDownContainer[^] 中。

添加此代码以在 DropDownContainer 中创建颜色框

Private Sub ColorPicker1_ColorPicked(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles ColorPicker1.ColorPicked

    Dim bm As Bitmap = New Bitmap(30, 20)
    Using g As Graphics = Graphics.FromImage(bm)
        g.FillRectangle(Brushes.White, 0, 0, 30, 20)
        g.FillRectangle(New SolidBrush(ColorPicker1.Value), 0, 0, 30, 20)
        DropDownContainer1.GraphicImage = bm.Clone
        bm.Dispose()
    End Using

    DropDownContainer1.CloseDropDown()

End Sub

ColorPickeInDropDown.jpg

替换颜色属性的MS颜色编辑器

如果您想使用 gColorPicker 而不是标准控件,只需引用 ColorPickerLib 并将此属性添加到该属性中

<Editor(GetType(gColorPickerDDEditor), GetType(UITypeEditor))> _

例如

<Editor(GetType(gColorPickerDDEditor), GetType(UITypeEditor))> _
Public Property BorderColor() As Color
    Get
        Return _borderColor
    End Get
    Set(ByVal Value As Color)
        _borderColor = Value
        Invalidate()
    End Set
End Property

ColorPickeInPropGrid.jpg

其工作原理在我的UITypeEditor文章中详细解释:UITypeEditorsDemo[^]。

gColorComboBox 和 gEnumBox

这些是添加到库中的几个附加控件。它们是 ComboBox 的扩展。gColorComboBox 列出所有已知颜色以及颜色样本。gEnumBox 采用我在编辑颜色时常用到的三种枚举,并为下拉项添加了一个样本示例。我决定将它们添加到此项目中,而不是创建一个全新的项目和库。

DashStyle

EmumHatch.png

HatchStyle

EmumHatch.png

LineJoin

EmumHatch.png

这样我就不必制作三个单独的控件了,我添加了一个属性,允许您使用所选枚举中的项目更新 ComboBox Items

Enum eStyle
    DashStyle
    HatchStyle
    LineJoin
End Enum

Private _enumStyle As eStyle = eStyle.Dashstyle

Public Property EnumStyle() As eStyle
    Get
        Return _enumStyle
    End Get
    Set(ByVal Value As eStyle)
        _enumStyle = Value
        Items.Clear()
        If Not DesignMode Then
            Select Case Value
                Case eStyle.DashStyle
                    Items.AddRange([Enum].GetNames(GetType(DashStyle)))
                Case eStyle.HatchStyle
                    Items.AddRange([Enum].GetNames(GetType(HatchStyle)))
                Case eStyle.LineJoin
                    Items.AddRange([Enum].GetNames(GetType(LineJoin)))
            End Select
        End If
    End Set
End Property

然后在 DrawItem 事件中,它根据当前的 EnumStyle 绘制 Item

历史

  • 版本 1.0 - 2008年10月
  • 版本 1.1 - 2008年10月
    • RaiseEvent ColorChanging(Me)Sub UpdateColor 中移到 Value Set Property 块中,并从 Sub UpdateColor 中删除了不必要的代码,以弥补 ColorChanging Event 中的漏洞。
  • 版本 1.2 - 2008年12月
    • 更新代码以符合 Option Strict On
    • 修复了初始化控件时的小问题
    • 更新鼠标事件
  • 版本 1.3 - 2009年4月
    • 添加了新的自定义RGB Trackbar 滑块
  • 版本 1.4 - 2011年9月
    • ColorPicked 事件中添加了 CurrentColorClosestColorName
    • 当颜色为黑色且点击了 Hue 时,自动将 SatBright 设置为 100
    • 删除了硬编码的 KnownColor 列表,并使用新的 SortColors 函数
  • 版本 1.5 - 2011年9月
    • 为吸管添加了自定义光标选项
  • 版本 1.6 - 2011年9月
    • 添加了如何将 gColorPicker 添加到 ToolStrip 的演示
  • 版本 1.7 - 2011年10月
    • 移动了 gColorComboBox 中颜色列表的初始化,以停止列表的多次加载
    • 新增 gEnumBox,以便更轻松地进行样式格式设置
    • gColorComboBox 添加了一些属性以匹配 gEnumBox
  • 版本 1.8 - 2012年1月
    • 添加了 UITypeEditor,以便 gColorPicker 可以在 PropertyGrid 中使用
© . All rights reserved.