【问题标题】:Eliminate Flickering in C# WinForms Application消除 C# WinForms 应用程序中的闪烁
【发布时间】:2015-11-23 14:01:30
【问题描述】:

我正在使用Visual Studio 2013 创建一个C# WinForm Application(用于触摸设备“MS Surface Hub”)。
我创建了两个表单:

  1. 第一个表单包含在表单加载时运行的介绍视频 (axWindowsMediaPlayer)
  2. 第二种形式包含菜单(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()
  • 一般来说没有什么魔法可以解决这个问题,你必须检查你的代码以避免不必要的重绘,这需要经验和耐心。

标签: c# forms winforms flicker


【解决方案1】:

我通过使用表单的sendToBackbringToFront 属性实现了零闪烁。我最初在 InitializeForm() 函数中加载了我的两个表单,然后在 Touch 事件上简单地在我的表单上设置这些属性。这样做可以消除加载表单的时间,即使用 .show().hide()

注意:我的两个表单都是static,因此我可以应用这些属性。在动态决定要加载哪个表单的情况下,我不确定这是否会产生预期的结果。欢迎任何更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2016-12-20
    • 2011-04-18
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多