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

带进度条的标签 [在状态栏中]

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (11投票s)

2007年11月23日

4分钟阅读

viewsIcon

74461

downloadIcon

1544

一篇介绍如何创建非常简单的带进度条文本标签的文章。

Screenshot - StatusBarLabelWithBar.png

引言

最近我需要一个非常简单的仪表盘嵌入到StatusStrip中,就像上面图片所示的那样。Visual Studio 2005中包含的ToolStripProgressBar几乎可以满足需求,但它不能在进度条上叠加文本。在本教程中,我将通过继承Label控件并重写OnPaint方法,向您展示如何创建一个带文本的简单进度条。然后,我将将其扩展到StatusStripLabel,以便添加到StatusStrip容器中。我使用Visual Basic完成了这项工作,但我确定它可以轻松地转换为C#。

Using the Code

首先,在您的项目中创建一个继承自Label类的新类

Public Class LabelWithBar
    Inherits Label 
 
End Class

通过继承Label控件,我们可以获得所有标准的Label方法和属性;例如TextTextAlignForeColorBackColorFont。构建项目后,您应该会在Toolbox中看到LabelWithBar。您可以将其拖放到窗体上,就像操作Label控件一样。

现在添加三个属性:ValueBarColorBarHeight

Public Property Value() As Integer
    Get
        Return mVal
    End Get 
 
    Set(ByVal Value As Integer) 
 
        ' Make sure that the value does not stray outside the valid range.

        Select Case Value
            Case Is < 0
                mVal = 0
            Case Is > 100
                mVal = 100
            Case Else
                mVal = Value
        End Select 
 
        ' Invalidate the control to get a repaint.

        Me.Invalidate()
    End Set
End Property
 
Public Property BarColor() As Color
    Get
        Return mbarColor
    End Get
 
    Set(ByVal Value As Color)
        mbarColor = Value 
 
        ' Invalidate the control to get a repaint.

        Me.Invalidate()
    End Set
End Property
 
Public Property BarHeight() As Integer
    Get
        Return mbarHeight
    End Get
    Set(ByVal value As Integer)
        Select Case value
            Case Is > Me.Size.Height, Is < 0
                mbarHeight = Me.Size.Height
            Case Else
                mbarHeight = value
        End Select
 
        ' Invalidate the control to get a repaint.

        Me.Invalidate()
    End Set
End Property

Value属性控制条的长度,类似于ProgressBarValue属性。在我的示例中,我将值限制为0到100之间的整数,表示填充百分比。将其扩展到使用像ProgressBar一样的MaximumMinimum属性很容易,但这足以应付目前的情况。BarColor属性控制条的颜色,而BarHeight属性控制条的高度或厚度。BarHeight被强制设置为小于标签高度的某个值。

现在我们可以通过重写OnPaint方法来绘制进度条

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs) 
 
    Dim g As Graphics = e.Graphics 
 
    Dim percent As Decimal = mVal / 100
    Dim brush As SolidBrush = New SolidBrush(BarColor)
    Dim rect As Rectangle = e.ClipRectangle
    Dim height As Integer = mbarHeight 
 
    rect.Width = rect.Width * percent
    If height = 0 Then height = rect.Height 
 
    rect.Y = (rect.Height - height) / 2
    rect.Height = height 
 
    ' Draw bar

    g.FillRectangle(brush, rect)
    MyBase.OnPaint(e) 
 
End Sub

此函数首先绘制一个指定颜色、高度和宽度的进度条。然后,它调用Label的本地OnPaint方法来绘制文本。请注意,如果BarHeight设置为0,则进度条的高度将默认为Label的高度。

这就是您需要了解的全部内容。您现在可以在Visual Studio的属性窗口中在设计时编辑控件的ValueBarColorBarHeight属性,或者在运行时在代码中进行编辑。

为了改进自定义控件,最好告诉Visual Studio每个属性的默认值。通过使用DefaultValue属性向每个类添加默认值来实现。对于ValueBarHeight属性,这意味着在属性声明之前的行上添加<DefaultValue(0)> _。对于BarColor属性,我们需要进行一些类型转换,使用<DefaultValue(GetType(Color), "Blue")> _。如果您的项目还没有导入System.ComponentModel,您可能需要导入它。

现在最后一步是创建一个能够添加到StatusStrip控件的版本。您需要做的就是重复以上步骤,但不是继承自Label类,而是继承自ToolStripStatusLabel类。

<System.ComponentModel.DesignerCategory("code")> _
<ToolStripItemDesignerAvailability_
    (ToolStripItemDesignerAvailability.StatusStrip)> _
Public Class ToolStripStatusLabelWithBar
    Inherits ToolStripStatusLabel 
 
End Class

类前面的属性指示Visual Studio该类可以嵌入到StatusStrip中。现在,将LabelWithBar类中的所有代码复制并粘贴到这个类中,重新生成,您就可以将ToolStripStatusLabelWithBar控件添加到您的StatusStrip控件中了。

完整的代码可以从本文顶部的链接下载。

关注点

虽然我过去创建过一些自定义控件,但这是我第一次深入研究设计时属性。总的来说,如果不是因为以下几次走弯路,这个项目本可以不到一天就完成。

在我创建LabelWithBar类的第一个尝试中,我试图继承ProgressBar控件并在上面绘制文本。我很快发现处理文本对齐、字体等比添加一个简单的进度条要困难得多。最终,继承Label控件并绘制一个简单的矩形要容易得多。

在我创建ToolStripStatusLabelWithBar类的第一个尝试中,我试图继承ToolStripControlHost并将之前创建的LabelWithBar类作为嵌入的控件。这被证明比必要的要困难得多。我花了近一天的时间试图让控件保留在设计时设置的SizeTextAlign属性。我从未成功过。我怀疑在幕后,ToolStripControlHost试图管理它与LabelWithBar之间的SizeTextAlign,这干扰了我试图实现的目标。最后,正如上面所示,直接将LabelWithBar类中的属性复制并粘贴到ToolStripStatusLabelWithBar中要容易得多。

历史

  • 2007年11月23日:发布原始文章
© . All rights reserved.