BusyBar






4.84/5 (77投票s)
您唯一需要的进度条

引言
有很多关于进度条的文章(在CodeProject [^] 中大约有十来篇),它们都有不同的属性。我编写 BusyBar
的目的是将所有不同的样式集成到一个控件中。我编写了大约二十五种样式,但 BusyBar
真正的美妙之处在于它易于扩展。我希望人们在编写新样式时能提供给我,以便将其包含在这个项目中。
Using the Code
首先,您必须将 BusyBar
添加到您的项目中。我已将 BusyBar
打包为一个 C# 源文件(BusyBar.cs)及其相关的 RESX 文件(BusyBar.resx)。Visual Studio 有点反复无常,所以请按顺序遵循以下说明
- 将这两个文件复制到您的项目目录。
- 向您的项目添加对 System.Design.dll 的引用。
- 将 BusyBar.cs 添加到您的项目;BusyBar.resx 将自动添加。
- 在设计器中打开 BusyBar.cs;我不知道为什么这有必要。
- 编译您的项目。
- 将您的程序集添加到工具箱。
以下是“将您的程序集添加到工具箱”步骤的详细说明(这并不那么明显)
- 显示您的工具箱。
- 选择工具箱上的“我的用户控件”选项卡。
- 右键单击并选择“添加/移除项...”
- “自定义工具箱”对话框出现。
- 单击“浏览...”
- 浏览到 (项目)/bin/Release 文件夹并选择您的 *.exe。
- 单击“确定”。
正如 VB.NET 开发人员所要求的,我现在也将其打包在一个控件库中。您现在应该在工具箱中拥有 BusyBar
控件和一些 Painter 组件。请注意,它们只在设计视图中打开表单时才启用。您现在可以向表单添加 BusyBar
控件了。首先,一个快速图表帮助您理解 BusyBar
的工作原理

BusyBar
类是一个自定义控件,它处理控件相关的内容,例如 CornerRadius
,以及数据属性,例如最小值、最大值和当前值。它还负责绘制边框,但其余的绘制工作则委托给 IPainter
的实例。我编写了一些 IPainter
的实现,每个实现都有各种 Preset
设置。
您现在可以向表单添加 BusyBar
实例了。这将绘制边框,但您需要选择一个 IPainter
来绘制客户端区域。您可以通过以下三种方式之一进行操作
- 向表单添加一个 Painter 实例(它们都派生自
Component
),并将BusyBar
的PainterObject
属性设置为指向您的 Painter。这可能是最简单的方法。然后,您可以在表单设计器中设置 Painter 的属性。请注意,所有 Painter 都具有Preset
属性。此属性不会被持久化,但设置它会将BusyBar
和 Painter 的属性设置为一些预定义值。 - 将
BusyBar
的PainterPreset
属性值设置为其中一个枚举值。在运行时,BusyBar
将创建相应 Painter 的实例。您可以通过BusyBar
的PainterWorker
属性访问此对象,并在表单后面的代码中设置其属性。 - 完全通过代码完成。您可以在代码中设置
BusyBar
的PainterObject
或PainterPreset
属性,然后像上面一样通过PainterWorker
属性设置 Painter 的属性。如果您自己编写自定义 Painter,这是使用它的方法。
就这样了。:) 您可以使用演示来测试各种设置,并查看目前可用的不同样式。
添加设计时位图
您会注意到 BusyBar
控件和 Painter 组件在工具箱中都有默认位图。如果您想要漂亮的位图,您需要执行几个额外的步骤
- 将位图添加到您的项目。在您的项目中创建一个名为“Bitmaps”的新文件夹,并将位图文件复制到其中。
- 设置构建操作。在解决方案资源管理器中选择位图文件,并将“构建操作”属性更改为“嵌入式资源”。
- 设置您的默认命名空间。在 BusyBar.cs 文件的顶部定义了一个名为
ResFinder
的类。将DefaultNamespace
常量的值更改为您的默认命名空间。有关解释,请参阅“兴趣点”。 - 构建您的项目。您可能需要重新构建您的解决方案。
- 从工具箱中删除旧的工具箱项。
- 再次将您的程序集添加到工具箱。
您现在应该会在工具箱中看到闪亮的新位图了 :)
画家
本节将帮助您选择一个 Painter,并解释每个 Painter 特有的属性。我没有包含不同预设的图像,因为它们太多了。您可以运行演示以查看可能的效果示例。
PainterLine
这是我编写的第一个 painter,仅仅是为了测试 BusyBar
控件。所以它相当简单,但可能有些用处。它只有一个预设,“Bar”,将线的宽度设置为 50,所以它显示为一块颜色。
PainterXP
这是尝试复制 .NET ProgressBar
控件。此 Painter 引入了“块”的概念。当 BlockLineWidth
属性大于 0 时,会在条形图上绘制一系列线条。当 BlockLineColor
属性设置为控件的 BackgroundColor
时,这会将条形图分成块。
它有两个预设:“System”,它将 Bar.Pin
属性设置为 BusyBar.Pins.Start
,这会将条形图锚定在左侧或顶部;以及“Startup”,它是 XP 在启动时显示的条形图的副本。
PainterPathGradient
这是最有用且可配置性最高的 Painter 之一。它使用 PathGradientBrush
绘制条形图,这意味着您可以在二维空间中设置颜色渐变。将 Shape
属性设置为其中一个枚举值以指定基本形状,然后设置 Color
属性以定义画笔。
它有五个预设:“Kitt”、“Circle”、“Startup”、“Startup2003”和“Noise”。这些展示了此 Painter 可以产生的广泛效果。如果您知道“Kitt”预设的来源,您将获得分数 :)
PainterClock
此 Painter 最适合较大、方形或略微矩形的 BusyBar
控件。它在边缘绘制 12 个标记和两个旋转的“指针”。它有两个预设:“Watch”和“Circle”。请注意,“Watch”预设采用 CP 颜色!
PainterSillyscope
这个 Painter 旨在模仿示波器。线条绘制为 GraphicsPath
。这由 Shape
和 Points
属性定义。如果 Shape
属性设置为 Line
,则调用 path.AddLines( points )
创建路径。这只会导致连接点的直线。
如果 Shape
属性设置为 Curve
,则调用 path.AddCurve( points, 1, points.Length - 3, tension / 100f )
来创建路径。这会导致连接中间点的曲线。两个端点不绘制,它们只是用于定义路径起点和终点的曲率。因此,此 Shape
需要至少四个点。
如果 Shape
属性设置为 Bezier
,则调用 path.AddBeziers( points )
创建路径。这会导致连接点的曲线。此 Shape
需要一个点作为起始位置,然后需要三个点来描述每个线段。因此,它必须有 4、7、10... (1 + 3n)... 个点。
请注意,由点数组描述的路径的“大小”无关紧要。路径会根据 HorizontalScale
和 VerticalScale
属性进行缩放,这些属性是 BusyBar
控件客户端区域的百分比。此外,如果控件处于垂直模式,路径会顺时针旋转 90 度,因此点数组必须始终水平设置。
这个 Painter 中有几个预设。“Triangle”、“Square”和“Saw”基于 Line
形状;“Sine”基于 Curve
形状;“Bezier”基于 Bezier
形状。另外两个预设,“Circle”和“Heartbeat”只是为了好玩 :)
PainterInstall
这个 Painter 是 OS 安装过程中显示的进度条的复制品。我是凭记忆写的;我觉得它差不多是对的。它有两个预设:“Install”,这是经典的安装条,和“LED”,它模仿一排(蓝色)LED。
PainterFrustratoBar
这是一个笑话(我希望)。它显示一个看起来像 IE 中的进度条。它显示值的对数,所以它一开始似乎很快,然后减慢。然后当它达到指定的百分比时会重置自己,所以它永远不会达到 100%。这是有人请求的(真的)!
编写自己的 Painter
所有 Painter 都必须实现 IPainter
接口
public interface IPainter : ICloneable
{
IPainter CreateCopy();
BusyBar BusyBar { get; set; }
void Reset();
void Paint( Graphics g, Region r );
}
您可能希望从现有类之一继承。派生结构如下所示
IPainter
PainterBase
PainterLine
PainterBlockBase
PainterXP
PainterFrustratoBar
PainterPathGradient
PainterClock
PainterSillyscope
PainterInstall
如果您从 PainterBase
派生,您只需重写 CreateCopy
和 Paint
方法。PainterBase
持有对 BusyBar
控件的引用,它通过受保护的 Bar
属性使其可用。它还处理 ICloneable
接口。
Paint
方法是最有趣的。它在 BusyBar
控件绘制完边框后,从 OnPaint
方法中调用。Graphics
参数使您能够进行绘图,而 Region
参数定义了可供您使用的客户端区域。Graphics
对象的剪辑区域已设置为此 Region
。
理解这种设计的最好方法是查看现有的具体 Painter 实现。
注意:要在演示中测试您的 Painter,请更改 Form1
的 Painter
属性以返回您的 Painter 实例(它在 Form1.cs 的末尾)。然后您就可以使用 PropertyGrid
s 调整设置了。
玩得开心:)
值得关注的点
让设计时位图工作真是件麻烦事。当 Visual Studio 嵌入资源时,它会假装默认命名空间给名称,而且这是不可配置的(有人认为这是个好主意!)。因为 BusyBar.cs 被设计为包含在任何项目中,所以默认命名空间是未知的。所以我添加了一个名为 ResFinder
的类在默认命名空间中,但是您必须手动设置 DefaultNamespace
常量。我找不到解决这个问题的方法 :(
Bob Powell 的网站帮助很大,特别是他的文章“如何找到难以捉摸的 ToolboxBitmap 图标” [^]。
结论
BusyBar
提供开箱即用的许多功能,但我希望人们能编写更多扩展,并通过电子邮件发送给我,以便包含在本文的更新中。当然会给予适当的致谢。
我写得很开心,特别是“Kitt”和“Heartbeat”预设非常令人满意。我希望您喜欢我所做的一切 :)
历史
- 2005年5月19日:版本 1
- 2005年5月26日:版本 2
- 修复了演示中的线程错误。
- 按要求移除了 SCC 链接。
- 按要求打包为强命名库程序集。
- 向
PainterXP
添加了预设“Startup”。 - 向
PainterPathGradient
添加了预设“Startup2003”。 - 添加了
PainterInstall
,带有两个预设。
- 2005年5月27日:版本 3
- 修复了
Minimum
不为零时的错误。 - 按要求添加了
PainterFrustratoBar
。
- 修复了