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






4.41/5 (11投票s)
2007年11月23日
4分钟阅读

74461

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

引言
最近我需要一个非常简单的仪表盘嵌入到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
方法和属性;例如Text
、TextAlign
、ForeColor
、BackColor
、Font
。构建项目后,您应该会在Toolbox
中看到LabelWithBar
。您可以将其拖放到窗体上,就像操作Label
控件一样。
现在添加三个属性:Value
、BarColor
和BarHeight
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
属性控制条的长度,类似于ProgressBar
的Value
属性。在我的示例中,我将值限制为0到100之间的整数,表示填充百分比。将其扩展到使用像ProgressBar
一样的Maximum
和Minimum
属性很容易,但这足以应付目前的情况。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的属性窗口中在设计时编辑控件的Value
、BarColor
和BarHeight
属性,或者在运行时在代码中进行编辑。
为了改进自定义控件,最好告诉Visual Studio每个属性的默认值。通过使用DefaultValue
属性向每个类添加默认值来实现。对于Value
和BarHeight
属性,这意味着在属性声明之前的行上添加<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
类作为嵌入的控件。这被证明比必要的要困难得多。我花了近一天的时间试图让控件保留在设计时设置的Size
和TextAlign
属性。我从未成功过。我怀疑在幕后,ToolStripControlHost
试图管理它与LabelWithBar
之间的Size
和TextAlign
,这干扰了我试图实现的目标。最后,正如上面所示,直接将LabelWithBar
类中的属性复制并粘贴到ToolStripStatusLabelWithBar
中要容易得多。
历史
- 2007年11月23日:发布原始文章