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

面向所有人的平滑进度条!

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (11投票s)

2005年2月12日

3分钟阅读

viewsIcon

88873

downloadIcon

1139

一个多功能的进度条控件,具有垂直和水平模式。

引言

此控件基于一篇 MS 知识库文章,标题为 “如何在 Visual Basic .NET 中创建平滑进度条”。 我对 KB 文章中显示的示例代码进行了一些更改和添加,包括添加了两个新功能并更正了一些程序逻辑。

背景

正如 KB 文章中所述,Visual Basic .NET 随附的 ProgressBar 控件仅支持标准设置,而不是早期版本中的标准和平滑设置。 该文章展示了如何创建自定义 UserControl 以提供平滑连续滚动的 ProgressBar

使用代码

SmoothProgressBar.vb 文件编译成一个类库 DLL,您可以使用它将 SmoothProgressBar 控件添加到 Visual Studio 的工具箱中。 有许多文章描述了 如何将控件添加到工具箱,因此我不会在此重复该信息。 将控件添加到工具箱后,选择它并将其拖放到您的窗体上。 现在您可以更改任何属性以适合您的喜好。 大多数其他属性是不言自明的,例如 ProgressBarColorMinimumMaximumValue 属性是您将在代码中更新以更改 ProgressBar 的“进度”的内容。 这通常通过递增(或递减)添加到窗体的 Timer 控件的 Tick 事件处理程序中的值来完成。 为此,我创建了一个 StepValue 属性,可以将其设置为正或负整数,以及一个 Stepit() 方法,该方法在调用时将 StepValue 添加到控件的 Value 属性。 这模拟了 .NET 中提供的 ProgressBar 控件的行为。 如果您不确定如何执行此操作,请参阅下载中包含的 SPB_test 项目中的 Form1.vb 中的代码。

关注点

正如我提到的,我向 KB 文章中提供的原始控件添加了两个新功能。 第一个使用 Horizontal 属性来控制 ProgressBar 中滚动的方向。 将其设置为 True 启用正常的水平滚动。 将其设置为 False 会导致滚动垂直移动。

第二个功能使用 Reverse 属性,默认为 False。 当设置为 True 时,滚动方向反转,即水平模式下从右到左,垂直模式下从上到下。 添加此功能需要更改 OnPaint 方法中的代码,如下所示

' Calculate area for drawing the progress.

With Me.ClientRectangle
   If isHorz Then
      rect.Width = rect.Width * percent
      If isRevs Then rect.X = .Width - rect.Width
   Else
      rect.Height = rect.Height * percent
      If Not isRevs Then rect.Y = .Height - rect.Height
   End If
End With

我还更改了 Value 属性的 setter 中的逻辑,从而大大减小了其大小和复杂性。 在这里,我计算了四个矩形,每个矩形对应于 HorizontalReverse 的组合,使用的代码行数与原始文章中用于获取一个矩形的代码行数大致相同……

Dim dm, dv, mm, mx As Integer
dm = max - min
dv = Math.Abs(val - oval)
mx = Math.Max(val, oval)
mm = Math.Min(val, oval)
Dim r As Rectangle

With Me.ClientRectangle
   If isHorz Then
      If isRevs Then
        r = 
         New Rectangle(.Width - mx * .Width / dm, 0, dv * .Width / dm, .Height)
        'r.X = .Width - r.X

      Else
        r = 
         New Rectangle(mm * .Width / dm, 0, dv * .Width / dm, .Height)
      End If
   Else
      If isRevs Then
        r = 
         New Rectangle(0, mm * .Height / dm, .Width, dv * .Height / dm)
      Else
        r = 
         New Rectangle(0, .Height - mx * .Height / dm, .Width, dv * .Height / dm)
      End If
   End If
End With

有趣的是,在原始文章中,Minimum 属性的 setter 实际上仅当传递的值小于零或大于最大值时才设置最小值,而 Maximum 属性的 setter 不会阻止设置小于零的值,甚至将 min 设置为相同的值! 我已将此行为更改为(我希望的)正确的行为。 此外,我还阻止将 min 和 max 设置为相同的值,因为这样做会导致引发异常,因为代码使用 max 和 min 之间的差(即 max-min)作为表达式中的除数来计算矩形的大小以在控件失效时更新(不能除以零!)。

我希望您喜欢这个控件,并且我要感谢 MS 为它提供了灵感(和大部分代码)。

本文下载中的部分代码 ©2005 Microsoft Corporation。

© . All rights reserved.