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

一个隐藏屏幕更新的帘子,并以漂亮的淡入淡出效果融合新旧内容

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (39投票s)

2006 年 9 月 18 日

5分钟阅读

viewsIcon

134306

downloadIcon

1755

在所有绘图完成之前冻结用户界面的部分,并平滑地融合旧内容和新内容。

目的

偶尔,您会遇到需要进行大规模屏幕更新的情况。我指的是那种使许多 UI 组件失效,并让您的桌面应用程序看起来像一个正在加载的网页的刷新。在这些更新期间,许多组件需要逐个绘制才能获得最终屏幕。当更新跨越多个绘制事件时,就会出现问题,从而使双缓冲等技术难以使用。最糟糕的是,您的用户会抱怨这种业余的外观,当然,您也不会觉得自己像个业余选手。所以您是否梦想过一种方法来隐藏您的工作进展,只显示最终结果?

这个组件就是为此而生的:在所有绘图完成之前冻结用户界面的部分,即使是多个绘制事件。然后,为了让事情更美好,新内容将使用漂亮的淡入淡出效果与旧内容平滑融合。所以现在您明白了:这是您为桌面应用程序添加 Web 2.0 风格的机会。

如果这听起来很有趣,这里有一个 Visual Studio 2005 C# 加载帘子窗体,可以集成到您的项目中。我称之为“帘子”,因为它类似于剧院的帘子,可以隐藏演员,同时他们正在准备下一场戏。

为什么不使用双缓冲技术?

也许您听说过 Windows Forms 的 DoubleBuffered 属性,并认为它应该很好用。虽然它在某些情况下可能很有用,但对于我们当前的问题,它有一些局限性。

  • 并非总是可行或容易,因为有些组件可能不在您的控制之下。例如,当您有一个 COM 组件使用设备上下文直接绘制自身时,缓冲技术就不是一个选项。
  • 无法跨越多个绘制事件。因此,当多个组件需要同时绘制时,您必须确保它们同时发生,否则,您将陷入网页加载综合症。
  • 不容易只定位屏幕的某些部分。
  • 没有现成的解决方案可以应用淡入淡出效果(所以忘掉 Web 2.0 的风味吧)。
  • 当您只想隐藏零点几秒的东西时,它相当笨重!

概念工作原理

  1. 在更新 UI 之前,将帘子覆盖在屏幕区域上。
  2. 帘子会截取屏幕快照,并将这张静态图像显示给用户。
  3. 同时,您进行繁重的更新工作,并重新排列屏幕,而不会让您的用户出现癫痫发作。
  4. 完成后,淡出帘子,让用户看到您的作品。

代码工作原理

  1. 将帘子导入到您的项目中。在 Visual Studio 2005 中,可以通过“项目”->“添加现有项”来完成,然后浏览到帘子文件 CurtainForm.cs
  2. 创建您的帘子对象并进行配置。如果您想同时更新多个 UI 部分,只需创建多个帘子!
    MT.CurtainForm myCurtain = new MT.CurtainForm();
  3. 将您的帘子显示在要更新的控件前面(最常见的情况)
    myCurtain.Show(myControl);

    或手动设置要更新的区域

    myCurtain.Bounds = new Rectangle(x, y, width, height);
    myCurtain.Show();
  4. 最后,淡出您的帘子
    myCurtain.Fade();

    或在没有淡入淡出效果的情况下将其隐藏

    myCurtain.Hide();

帘子属性

这些设置非常精细,仅为最狂热的您提供!

FadeDuration

指示淡入淡出总时间(以毫秒为单位)。我个人使用 250 毫秒的时间,因为它不会太长而令人恼火,并且足以让用户正确看到已更改的内容。

FrameDuration

这是动画精度或质量。类似于视频游戏中的每秒帧数,您可以根据需要使用更多的 CPU 资源。您可以通过设置每帧的持续时间(以毫秒为单位)来指定精度。因此,如果您设置每帧 50 毫秒,这相当于每秒 20 帧。

ClickThrough

指示用户在帘子淡入淡出时是否可以点击穿过。当不淡入淡出时,此设置无效,因为帘子的目的是隐藏后面的内容。当使用较长的淡入淡出持续时间时很有用,因为用户可以立即与新内容进行交互。

限制

显示帘子时无法调整区域大小。为避免调整大小,我在容器窗体中使用以下代码

显示帘子之前

MinimumSize = this.Size;
MaximumSize = this.Size;

帘子隐藏后

MinimumSize = new Size(0,0);
MaximumSize = new Size(0,0);

如果您的窗口无法调整大小,那么这对您来说不是问题。

示例项目

示例项目包含两组可以更新的列表框。一组使用帘子,另一组不使用。该示例说明了当多个 UI 组件需要刷新时出现的问题:它们无法同时刷新。如果您发现列表框更新不是真正的问题(因为调用 BeginUpdateEndUpdate 毕竟会隐藏中间结果),那么想象一下,如果列表框换成一些酷炫的自定义控件。

参考文献

结论

这种“帘子技术”非常轻量级且可重用,无论需要隐藏的是什么 UI 组件。我在使用 MSHTML 组件(Microsoft HTML 编辑器)时创建了它。我需要一种方法来隐藏所有网页加载工作,当使用桌面应用程序进行编辑时,这有点令人讨厌。当然,我是一名专业人士。

© . All rights reserved.