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

ColorBar -渐变彩色进度条

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (47投票s)

2008年4月26日

CPOL

3分钟阅读

viewsIcon

136709

downloadIcon

6837

ColorBar是一个使用VB.NET编写的渐变彩色进度条控件。

ColorBar_Sample.JPG

引言

ColorBar 是一个用VB.NET编写的渐变彩色进度条控件。它被创建用来增加我的应用程序中进度条的趣味性。

Using the Code

在你的项目中,添加对 ColorBar.dll 的引用。你也可以将控件添加到 VS 工具箱,这样你就可以在你的表单上拖放它,或者从你的代码中实例化它(这是示例应用程序所做的)。

该控件的使用类似于常规的进度条控件。相应地设置 MinimumMaximum 属性;然后增加 Value 属性。Smoothness 属性控制从一种颜色到下一种颜色的渐变粗细程度。

BarStyle 属性可以设置为 Expand, Flow, 或 Block。一个 Expand 进度条从左向右扩展,包含所有颜色。一个 Flow 进度条从左向右流动,依次显示每种颜色,最后,一个 Block 风格的进度条是一个带有“突出”块的流动条。 Block 风格的进度条(在圆形方向上不可用)受控件的宽度、颜色列表中的颜色数量和渐变的平滑度的影响。

一个最小平滑度的 ColorBar

ColorBar_Chunky.JPG

一个块状风格的 ColorBar

ColorBar_Blocks.JPG

彩虹色,ROYGBIV,加上青色,是控件中使用的默认颜色。 如果你想使用你自己的颜色,只需创建一个至少包含两种颜色的列表,并将此列表分配给 ColorList 属性。要恢复到默认列表,将 ColorList 属性的值设置为 Nothing。 长的颜色列表将开始聚集在一起,并且在短长度的控件中可能看起来不 "平滑" 。

带有自定义颜色的 ColorBar

ColorBar_2Color.JPG

带有默认颜色的垂直 ColorBar

ColorBar_Vertical.JPG

带有默认颜色和厚度的圆形 ColorBar

ColorBar_Circular.JPG

带有自定义颜色和厚度的圆形 ColorBar

ColorBar_Thickness.JPG

创建 ColorBar 控件 (从代码) 简单直接

Dim cb as ColorBar

' instance the control - in Form Load event perhaps
cb = New ColorBar
cb.Size = New Size(300, 18)
cb.Location = New Point((Me.ClientRectangle.Width / 2) - (cb.Size.Width / 2), 50)
cb.Visible = True
cb.Parent = Me
Me.Controls.Add(cb)

' set initial properties
cb.Smoothness = ColorBar.MaxSmoothness
cb.Style = ColorBar.BarStyle.Expand

添加自定义颜色也很容易

' create a list of custom colors
Dim lstColors As New List(Of Color)
lstColors.Add(Color.Red)
lstColors.Add(Color.Green)

' assign to control
cb.ColorList = lstColors

删除自定义颜色

cb.ColorList = Nothing

关注点

该控件是双缓冲的,以避免闪烁

Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or _
            ControlStyles.DoubleBuffer Or ControlStyles.Opaque, True)
Me.UpdateStyles()

WM_ERASEBKGND 消息也被忽略,试图避免闪烁

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
      If m.Msg = &H14 Then ' ignore WM_ERASEBKGND
          Return
      End If
      MyBase.WndProc(m)
End Sub

插值颜色列表使用以下例程创建。对于每两种颜色,都会找到一个插值颜色并将其插入回列表中。

Private Function InterpolateColors(ByVal color1 As Color, ByVal color2 As Color) As Color
    Return Color.FromArgb(CInt((CInt(color1.R) + CInt(color2.R)) / 2), _
                    CInt((CInt(color1.G) + CInt(color2.G)) / 2), _
                    CInt((CInt(color1.B) + CInt(color2.B)) / 2))
End Function

Private Sub BuildColorList(ByRef lstAdd As List(Of Color))

    lstColors = New List(Of Color)

    Dim c As Color
    For Each c In lstAdd
        lstColors.Add(c)
    Next

    Dim idx As Integer ' lstColors index
    Dim cnt As Integer ' lstColors item count
    Dim sdc As Integer ' sub-divide count

    For sdc = 0 To m_Smoothness Step 1
        idx = 0
        cnt = lstColors.Count - 1
        While idx < cnt
            lstColors.Insert(idx + 1, InterpolateColors(lstColors(idx), _
                             lstColors(idx + 1)))
            idx += 2
            cnt += 1
        End While
    Next sdc

End Sub

进度条的绘制在 OnPaint 事件中完成。 它将“完成”的矩形分成每种颜色的相等部分。

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

    e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), Me.ClientRectangle)

    Dim percentComplete As Single = CSng((m_Value - m_Minimum) / _
                                         (m_Maximum - m_Minimum))

    If percentComplete <= 0.0F Then Exit Sub
    If percentComplete > 1.0F Then percentComplete = 1.0F

    Dim fullWidth As Single = CSng(Me.ClientRectangle.Width - BorderWidth)
    Dim totalWidth As Single = fullWidth * percentComplete

    Dim barWidth As Single
    If m_Style = BarStyle.Expand Then
        barWidth = totalWidth
    Else
        If m_Style = BarStyle.Flow Or m_Style = BarStyle.Block Then
            barWidth = fullWidth
        End If
    End If
    barWidth /= CSng(lstColors.Count)

    Dim height As Single = CSng(Me.ClientRectangle.Height - BorderWidth)
    Dim halfBorder As Single = CSng(BorderWidth / 2)
    Dim x As Single = halfBorder
    Dim idxColor As Integer = 0

    For x = halfBorder To totalWidth Step barWidth
        e.Graphics.FillRectangle(New SolidBrush(lstColors(idxColor)), x, _
                                 halfBorder, barWidth, height)
        If barWidth > 4 And Me.Style = BarStyle.Block Then
            ControlPaint.DrawBorder(e.Graphics, New Rectangle(CInt(x), _
                         CInt(halfBorder), CInt(barWidth), CInt(height)), _
                         Color.Gray, ButtonBorderStyle.Outset)
        End If
        If idxColor < lstColors.Count Then
            idxColor += 1
        End If
    Next

    If (x < (Me.ClientRectangle.Width - halfBorder)) And percentComplete = 1.0 Then
        If idxColor < lstColors.Count Then
            e.Graphics.FillRectangle(New SolidBrush(lstColors(idxColor)), x, halfBorder, _
                     ((Me.ClientRectangle.Width - halfBorder) - x), height)
        End If
    End If

    MyBase.OnPaint(e)

End Sub

尽情享用!

建议

通过定义你自己的 OnPaint 方法和/或修改属性,可以修改 ColorBar 以便以任何你想要的方式绘制(或表现)。 也许,从 Windows.Forms 基类控件而不是 UserControl 继承,然后使用 ControlPaint 类绘制你自己的边框。有很多可能性。

随机想法/改进

  • 使用 C# 重新编码(以允许使用不是关键字的属性名称)。
  • 添加一个 Step 属性和 PerformStep/Increment 方法(某些人可能会发现这些很有用)。
  • 控件属性可以从 Windows Forms 设计器设置,但是手动输入的颜色列表不会被保留。
  • 灰度选项。
  • 使用 GDI 或 GDI+ 渐变,而不是 DIY 的方式。(DIY 方法更有趣 :))。
  • Marquee 风格的控件。
  • 显示完成百分比或当前值。
  • 线程安全。

历史

  • 初始创建 - 2008年4月26日。
  • 更正拼写/格式 - 2008年5月3日。
  • 添加了画笔缓冲和其他小的改进 - 2008年5月24日。
  • 删除了 Finalize 方法 - 2008年5月24日。
  • 添加了垂直和圆形方向;可逆的颜色列表;圆形类型的可变厚度;其他小的代码改进 - 2008年6月14日。
© . All rights reserved.