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






4.83/5 (39投票s)
2006 年 9 月 18 日
5分钟阅读

134306

1755
在所有绘图完成之前冻结用户界面的部分,并平滑地融合旧内容和新内容。
目的
偶尔,您会遇到需要进行大规模屏幕更新的情况。我指的是那种使许多 UI 组件失效,并让您的桌面应用程序看起来像一个正在加载的网页的刷新。在这些更新期间,许多组件需要逐个绘制才能获得最终屏幕。当更新跨越多个绘制事件时,就会出现问题,从而使双缓冲等技术难以使用。最糟糕的是,您的用户会抱怨这种业余的外观,当然,您也不会觉得自己像个业余选手。所以您是否梦想过一种方法来隐藏您的工作进展,只显示最终结果?
这个组件就是为此而生的:在所有绘图完成之前冻结用户界面的部分,即使是多个绘制事件。然后,为了让事情更美好,新内容将使用漂亮的淡入淡出效果与旧内容平滑融合。所以现在您明白了:这是您为桌面应用程序添加 Web 2.0 风格的机会。
如果这听起来很有趣,这里有一个 Visual Studio 2005 C# 加载帘子窗体,可以集成到您的项目中。我称之为“帘子”,因为它类似于剧院的帘子,可以隐藏演员,同时他们正在准备下一场戏。
为什么不使用双缓冲技术?
也许您听说过 Windows Forms 的 DoubleBuffered
属性,并认为它应该很好用。虽然它在某些情况下可能很有用,但对于我们当前的问题,它有一些局限性。
- 并非总是可行或容易,因为有些组件可能不在您的控制之下。例如,当您有一个 COM 组件使用设备上下文直接绘制自身时,缓冲技术就不是一个选项。
- 无法跨越多个绘制事件。因此,当多个组件需要同时绘制时,您必须确保它们同时发生,否则,您将陷入网页加载综合症。
- 不容易只定位屏幕的某些部分。
- 没有现成的解决方案可以应用淡入淡出效果(所以忘掉 Web 2.0 的风味吧)。
- 当您只想隐藏零点几秒的东西时,它相当笨重!
概念工作原理
- 在更新 UI 之前,将帘子覆盖在屏幕区域上。
- 帘子会截取屏幕快照,并将这张静态图像显示给用户。
- 同时,您进行繁重的更新工作,并重新排列屏幕,而不会让您的用户出现癫痫发作。
- 完成后,淡出帘子,让用户看到您的作品。
代码工作原理
- 将帘子导入到您的项目中。在 Visual Studio 2005 中,可以通过“项目”->“添加现有项”来完成,然后浏览到帘子文件 CurtainForm.cs。
- 创建您的帘子对象并进行配置。如果您想同时更新多个 UI 部分,只需创建多个帘子!
MT.CurtainForm myCurtain = new MT.CurtainForm();
- 将您的帘子显示在要更新的控件前面(最常见的情况)
myCurtain.Show(myControl);
或手动设置要更新的区域
myCurtain.Bounds = new Rectangle(x, y, width, height); myCurtain.Show();
- 最后,淡出您的帘子
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 组件需要刷新时出现的问题:它们无法同时刷新。如果您发现列表框更新不是真正的问题(因为调用 BeginUpdate
和 EndUpdate
毕竟会隐藏中间结果),那么想象一下,如果列表框换成一些酷炫的自定义控件。
参考文献
- 制作一个可点击穿透的窗口 - 我使用了 Marc 的技术,他处理了
WM_NCHITTEST
消息。 - 防止窗口获得焦点,将焦点交还给非活动窗口 - 不完美,因为窗口可能会闪烁,但这对于这个组件来说已经足够了。
结论
这种“帘子技术”非常轻量级且可重用,无论需要隐藏的是什么 UI 组件。我在使用 MSHTML 组件(Microsoft HTML 编辑器)时创建了它。我需要一种方法来隐藏所有网页加载工作,当使用桌面应用程序进行编辑时,这有点令人讨厌。当然,我是一名专业人士。