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

BusyBar

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (77投票s)

2005年5月19日

CPOL

9分钟阅读

viewsIcon

255767

downloadIcon

3300

您唯一需要的进度条

Sample Image - BusyBar_2.png

引言

有很多关于进度条的文章(在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 来绘制客户端区域。您可以通过以下三种方式之一进行操作

  1. 向表单添加一个 Painter 实例(它们都派生自 Component),并将 BusyBarPainterObject 属性设置为指向您的 Painter。这可能是最简单的方法。然后,您可以在表单设计器中设置 Painter 的属性。请注意,所有 Painter 都具有 Preset 属性。此属性不会被持久化,但设置它会将 BusyBar 和 Painter 的属性设置为一些预定义值。
  2. BusyBarPainterPreset 属性值设置为其中一个枚举值。在运行时,BusyBar 将创建相应 Painter 的实例。您可以通过 BusyBarPainterWorker 属性访问此对象,并在表单后面的代码中设置其属性。
  3. 完全通过代码完成。您可以在代码中设置 BusyBarPainterObjectPainterPreset 属性,然后像上面一样通过 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。这由 ShapePoints 属性定义。如果 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)... 个点。

请注意,由点数组描述的路径的“大小”无关紧要。路径会根据 HorizontalScaleVerticalScale 属性进行缩放,这些属性是 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 派生,您只需重写 CreateCopyPaint 方法。PainterBase 持有对 BusyBar 控件的引用,它通过受保护的 Bar 属性使其可用。它还处理 ICloneable 接口。

Paint 方法是最有趣的。它在 BusyBar 控件绘制完边框后,从 OnPaint 方法中调用。Graphics 参数使您能够进行绘图,而 Region 参数定义了可供您使用的客户端区域。Graphics 对象的剪辑区域已设置为此 Region

理解这种设计的最好方法是查看现有的具体 Painter 实现。

注意:要在演示中测试您的 Painter,请更改 Form1Painter 属性以返回您的 Painter 实例(它在 Form1.cs 的末尾)。然后您就可以使用 PropertyGrids 调整设置了。

玩得开心:)

值得关注的点

让设计时位图工作真是件麻烦事。当 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
© . All rights reserved.