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

带许多附加功能的动画进度条控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (82投票s)

2006年5月13日

CPOL

8分钟阅读

viewsIcon

252746

downloadIcon

39746

一个扩展的图片框、一个动画图片框和一个动画进度条,它们都在同一个组件中。

Sample Image - Screenshot.png

目录

引言

这个组件的想法来自于我看到的 Iconits 文章[^]。这个想法非常好,当我将鼠标悬停在从左到右的图标上时,我想到这可以做一个很棒的进度条。此外,我缺少一些功能和自定义选项,而且由于我already有一个完全工作的动画组件(Animating Windows Forms[^]),我决定自己构建一个组件。

背景

要完全理解代码,你需要了解 Windows Forms、Timer、设计器支持等等。我不会详细描述所有内容。请参阅 参考文献,其中包含详细描述我的实现部分的文章。在我 menuju 最终的进度条控件的过程中,我实现了几个相互堆叠的辅助控件,这帮助我将整个大问题分解成小块。这样做应该时刻铭记在每个开发者的心中。它不仅有助于保持类的小型化,从而不会失去概览,而且在这种情况下,它还产生了一些可以独立于实际进度条使用的控件。

使用代码

使用起来非常直接。总共有四个控件,都可以通过在设计器中将它们拖到 Form 上来使用。几乎所有内容都可以通过设计器进行自定义,所以请开始探索吧。

示例

我在下载文件中投入了大量精力提供好的示例。它们涵盖了该组件的大部分功能,所以如果你想知道不同控件的功能,请随意尝试。下载文件之所以如此之大,主要是因为示例中包含了图像。组件本身相当小。

架构

如前所述,我不会在此赘述细节,只会描述类之间的关系。一切都已很好地记录在案,并且还包含一个帮助文件作为程序员参考。

ExtendedPictureBox

该控件 在某种程度上 类似于 PictureBox 类。至少,两者都具有显示 Image 的通用功能。它具有用于应用 alpha、旋转、渐变背景色等的属性。此外,它还有一个 BaseSizeMode 属性,该属性与 Zoom 属性一起处理如何调整显示的 Image 的大小。最后,它能够显示第二个 Image,而无需 alpha 混合和调整大小,并支持自定义旋转和对齐。

其中一些属性不仅可以单独访问或设置,还可以通过 State 属性进行修改。这个属性在此控件中没有实际的好处,但它包含了所有将在稍后阶段进行动画处理的属性。

此功能在示例应用程序主窗体的左上角示例中得到了演示。

AnimatedPictureBox

此类派生自 ExtendedPictureBox。它使用了我的动画组件,因此对于每个动画属性,我都实现了一个动画类和一个将它们绑定在一起的动画器(所有内容都可以在 Animators 子命名空间中找到)。主要扩展是 Animate 函数,它接收一个新的 State 对象。调用它将导致从当前状态平滑动画到新状态。此外,它还有多个属性、函数和事件来控制动画。

AnimatedPictureButton

这个实际上并不是进度条所必需的,但我仍然实现了它。它派生自 AnimatedPictureBox,现在包含两个 StateStartState结束状态。第一个将在鼠标光标不位于控件上方时显示。当鼠标进入控件时,它会将状态动画化到第二个状态。

左下角的示例显示了这一点。别忘了点击随之出现的窗体右下角的按钮,其中包含更多预定义的示例。另外请注意,示例选择器就是用这个控件构建的。

AnimatedPicturesProgressBar

最后,我们来到了这个组件的实际目标。AnimatedPicturesProgressBar 有一个 Steps 属性,其中可以添加描述进度条每个步骤视觉外观的 ProgressSteps。对于每一步,都会创建一个 AnimatedPictureBox 并将其一个接一个地水平放置在控件中。您可以定义三个状态,分别代表尚未开始、进行中或已完成的步骤。此外,您可以定义当前步骤是否以及如何获得一些额外的动画,以及一些影响动画的其他属性。添加完所有步骤并设置所有属性后,需要调用 EndInit(如果您使用设计器完全配置了进度条,设计器将为您完成此操作),如果这是第二次运行,还需要调用 Reset。然后,对于每个起始步骤,调用 NextStep 将使进度前进一个步骤。重要的是要理解,如果主线程被一些繁重的操作阻塞,动画将不会显示(就像 GUI 中的任何其他重绘一样)。有几种方法可以避免这种情况

  • 在一个单独的线程中执行处理。别忘了使用 InvokeNextStep 的调用委托到线程边界。这是在不产生任何严重性能损失的情况下保持动画流畅的最佳方法。
  • BlockNextStepCall 设置为 true。这样,调用 NextStep 将在过渡完成后返回。性能可能会略有下降,因为您的处理将在动画进行时停止,并且在处理步骤时旋转小附加图像和背景色过渡将不可见。
  • 自己确保控件被重绘。这可以通过调用 RefreshApplication.DoEvents 来完成。请记住,过于频繁地调用这些可能会导致严重的性能损失,而调用不够频繁则会导致动画不够流畅或变慢。因此,我建议使用以上两种解决方案之一。

请查看右下角的示例。它显示了所有可能的组合。

内存消耗

关于内存消耗,一个小说明,以免有人抱怨该组件分配了太多内存:这是完全正常的! 如你所料,此组件需要大量的绘图逻辑。我还创建了内存中的位图以简化这一点。当然,这会促使 CLR 分配大量内存,但它也会定期释放它。当然,我可以强制垃圾回收器执行其工作并更频繁地显式处置,但在托管环境中这并非必需,它甚至可能降低性能。

参考文献

几篇文章在实现细节上帮助了我。最重要的几篇是

待办事项

  • 仍然可以对一些性能进行调整(尽管我已经尽力使其快速)。
  • 我渴望根据此处提出的有用功能来扩展此组件。所以,如果任何人有进一步的建议,请随时在此处发布。

历史

  • 2006 年 5 月 13 日 - 版本 1.0.0
    • 初始发布。
  • 2006 年 7 月 1 日 - 版本 1.1.0
    • AnimatedPictureButton 被禁用或容器 Form 未处于活动状态时,它将不再响应鼠标进入事件。
    • ExtendedPictureBox 和所有派生控件添加了对透明背景色的支持。两种颜色都可以具有 alpha 值。唯一的限制是,为了使其正常工作,BackColor 的 alpha 值必须小于 255。仅在 BackColor2 上设置 alpha 值无效。请注意,启用透明度可能会大大降低性能(取决于控件下方绘制的内容)。

      我还增强了一些示例来测试这一点。

    • ExtendedPictureBox 或任何派生控件被禁用时,图像现在将相应地绘制。我还添加了一个新的属性 AllowDisabledPainting 来关闭此新功能。
  • 2006 年 7 月 15 日 - 版本 1.2.0
    • 为所有四个控件添加了显示文本的支持。动画控件可以动画文本的大小、旋转、光晕宽度、光晕颜色和前景色。此功能还支持文本对齐。请参阅示例 - 这增加了一些非常酷的效果。
    • 因此,一些构造函数已更改,并且可能会让设计器感到困惑。如果您在设计器中为 AnimatedProgressBar 定义了步骤,这只会造成困扰。请手动更正这些错误。
    • 在 1.1.0 版中,ForeColor 改变了边框的颜色。现在它改变了文本的颜色。边框的颜色现在可以通过新的 BorderColor 属性进行调整。
    • 更改了我所有 Color 类型属性的 Editor,它允许在编辑器中设置颜色的 alpha 值。有关详细信息,请参阅 此处[^]。
  • 2006 年 11 月 18 日 - 版本 1.3.0
    • 为图像添加了阴影效果。
    • 添加了总共三个偏移属性,增强了可视化和动画效果。
    • AnimatedPictureButton 对鼠标单击做出反应,为用户提供视觉反馈,表明他们按下了按钮。
    • 其他几个小的更改和修复。
    • 更改了示例以反映这些更改。由于示例窗体变得太大,我用 NicolNghia 的 TrackBar 替换了普通的 TrackBar,它更小。您可以在他的文章中找到该控件:Advanced TrackBar (Slider) Control with MAC Style (C# and VB.NET)[^]。
© . All rights reserved.