【发布时间】:2015-11-23 14:01:30
【问题描述】:
我正在使用Visual Studio 2013 创建一个C# WinForm Application(用于触摸设备“MS Surface Hub”)。
我创建了两个表单:
- 第一个表单包含在表单加载时运行的介绍视频 (axWindowsMediaPlayer)
- 第二种形式包含菜单(Flash 文件)
如果用户通过触摸 Form 1 上的屏幕进行中断,则介绍视频将停止播放并移至 Form 2。这是我实现此目的的代码:
private void axWindowsMediaPlayer_ClickEvent(object sender, AxWMPLib._WMPOCXEvents_ClickEvent e)
{
Player.close();
var menu = new Menu();
menu.Closed += (s, args) => this.Close();
menu.Show();
this.Hide();
}
但是,当我检查从 Form 1 到 Form 2 的转换时,我观察到 flicker effect(即我观察到后屏幕显示了几分之一秒)。如何消除这种影响?
我在 Stack Forums 上遇到了很多问题,也阅读了很多博客,但没有找到可行的解决方案。有人建议我在表单中使用 DoubleBuffered 属性,但它给了我以下错误:
只有赋值、调用、递增、递减、等待和新对象表达式可以用作语句
另一个建议是使用WS_EX_COMPOSITED 0x02000000L,但是我没有找到足够的注释来说明如何在我的代码中准确地实现它。 MSDN 上对此的引用:
使用双缓冲以自下而上的绘制顺序绘制窗口的所有后代。有关详细信息,请参阅备注。如果窗口的类样式为 CS_OWNDC 或 CS_CLASSDC,则不能使用。
我想知道是否有消除闪烁效果的解决方法。
【问题讨论】:
-
你是如何使用
DoubleBuffered的?此外,请注意某些闪烁在 WinForms 中是不可避免的(部分原因是 Microsoft 在 Windows Vista 及更高版本中削弱了 GDI/GDI+)。如果你的目标是 Surface Hub,那么你应该使用 XAML 作为应用程序的 UI 框架,而不是 WinForms。 -
我在 MediaPlayer Click 函数中使用了 DoubleBuffered...this.DoubleBuffered...我也尝试在 InitializeForm() 函数中使用它
-
使用双缓冲的方式是将其设置为 true。
this.DoubleBuffered = true; -
...但我不认为双缓冲是你的问题。我认为问题在于,您在显示另一个表单之前隐藏了现有表单 - 所以有一小部分时间您没有显示任何内容。您能否尝试一些简单的方法,例如将呼叫移至
this.Hide()下方menu.Show() -
一般来说没有什么魔法可以解决这个问题,你必须检查你的代码以避免不必要的重绘,这需要经验和耐心。