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






4.95/5 (82投票s)
一个扩展的图片框、一个动画图片框和一个动画进度条,它们都在同一个组件中。
目录
引言
这个组件的想法来自于我看到的 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
,现在包含两个 State
:StartState
和 结束状态
。第一个将在鼠标光标不位于控件上方时显示。当鼠标进入控件时,它会将状态动画化到第二个状态。
左下角的示例显示了这一点。别忘了点击随之出现的窗体右下角的按钮,其中包含更多预定义的示例。另外请注意,示例选择器就是用这个控件构建的。
AnimatedPicturesProgressBar
最后,我们来到了这个组件的实际目标。AnimatedPicturesProgressBar
有一个 Steps
属性,其中可以添加描述进度条每个步骤视觉外观的 ProgressSteps
。对于每一步,都会创建一个 AnimatedPictureBox
并将其一个接一个地水平放置在控件中。您可以定义三个状态,分别代表尚未开始、进行中或已完成的步骤。此外,您可以定义当前步骤是否以及如何获得一些额外的动画,以及一些影响动画的其他属性。添加完所有步骤并设置所有属性后,需要调用 EndInit
(如果您使用设计器完全配置了进度条,设计器将为您完成此操作),如果这是第二次运行,还需要调用 Reset
。然后,对于每个起始步骤,调用 NextStep
将使进度前进一个步骤。重要的是要理解,如果主线程被一些繁重的操作阻塞,动画将不会显示(就像 GUI 中的任何其他重绘一样)。有几种方法可以避免这种情况
- 在一个单独的线程中执行处理。别忘了使用
Invoke
将NextStep
的调用委托到线程边界。这是在不产生任何严重性能损失的情况下保持动画流畅的最佳方法。 - 将
BlockNextStepCall
设置为true
。这样,调用NextStep
将在过渡完成后返回。性能可能会略有下降,因为您的处理将在动画进行时停止,并且在处理步骤时旋转小附加图像和背景色过渡将不可见。 - 自己确保控件被重绘。这可以通过调用
Refresh
或Application.DoEvents
来完成。请记住,过于频繁地调用这些可能会导致严重的性能损失,而调用不够频繁则会导致动画不够流畅或变慢。因此,我建议使用以上两种解决方案之一。
请查看右下角的示例。它显示了所有可能的组合。
内存消耗
关于内存消耗,一个小说明,以免有人抱怨该组件分配了太多内存:这是完全正常的! 如你所料,此组件需要大量的绘图逻辑。我还创建了内存中的位图以简化这一点。当然,这会促使 CLR 分配大量内存,但它也会定期释放它。当然,我可以强制垃圾回收器执行其工作并更频繁地显式处置,但在托管环境中这并非必需,它甚至可能降低性能。
参考文献
几篇文章在实现细节上帮助了我。最重要的几篇是
- 对于动画,我自己的组件 Animating Windows Forms[^]。
- 最初的想法和一些使用的图像来自 hanifku 的 Iconits 文章[^]。
- 对于过去的参考,Christian Graus 的系列文章 Image Processing for Dummies[^] 是一个很好的资源。
- 关于自定义集合的设计器支持,灵感来自 Daniel Zaharia 的 How To Edit and Persist Collections with CollectionEditor[^]。
- 一些图标来自 FamFamFam[^]。
待办事项
- 仍然可以对一些性能进行调整(尽管我已经尽力使其快速)。
- 我渴望根据此处提出的有用功能来扩展此组件。所以,如果任何人有进一步的建议,请随时在此处发布。
历史
- 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)[^]。