【问题标题】:Winform with thousands of controls rendering performance具有数千个控件渲染性能的 Winform
【发布时间】:2014-02-12 20:30:54
【问题描述】:

十年前,我创建了一个简单的俄罗斯方块游戏来学习 .NET 和 WinForms。我创建了一个由标签控件组成的 10 x 30 网格。这些标签链接到包含每个块的图像的 ImageList。几周前,我的朋友要求为 LAN 派对提供俄罗斯方块游戏,所以我拿走了我的旧俄罗斯方块游戏,并复制了网格和标签以支持 10 名玩家。

游戏核心运行良好。但是,对于超过 3000 个标签,渲染开始变得困难。

所以这是我的问题:有没有办法改进我的应用程序的呈现?

我可以替换其他用户控件的标签,但我想避免陷入 DirectX / OpenGL 绘图(即使这是最好的解决方案,我也没有足够的时间来完成学习曲线)

【问题讨论】:

    标签: .net winforms rendering


    【解决方案1】:

    这是一种非常缓慢的方式,您不能真正期望它执行得很快。 您可以做的是仅使用 1 个控件而不是数千个控件 - 它将用作绘图画布。

    您应该覆盖控件上的 onpaint 事件并以这种方式绘制您的游戏状态。 您将在事件 args 中找到一个图形对象,并使用 FillRectangle 之类的函数您应该能够绘制所有内容。

    虽然这也可能导致一些闪烁,但 WinForms 首先不适用于此类东西 - 但它应该适合您的情况。

    我也明白这会改变你的概念,并且需要大量的编码更改,但它比 directx / opengl 路由要容易得多。

    祝你好运!

    【讨论】:

    • 有趣。我会试一试,看看它是否适合我的代码。
    【解决方案2】:

    表单上的每个控件都有自己的句柄,并被视为一个单独的窗口。窗口化不能很好地处理大量控件(就窗口化而言,WPF 不会为每个控件使用单独的窗口句柄,而是为整个窗口使用一个。)。

    3000 多个控件不是一个好主意,您知道这一点,但尽管我们对您的应用知之甚少,但让我们尝试使用创可贴!

    • 尽量不要使用透明背景色,否则会导致额外的绘制调用。该控件并不是真正透明的,它查看其父控件的背景并将背景复制到自身(OnPaintBackground)。在您的示例中对数千个控件重复此操作,您可以看到这种复合。 (当然如果你正在使用它)

    • 您是否隐藏了任何控件,如果是,您是使用 Visible 属性还是使用控件的 BackColor 实现此目的?通过使不必要的控件不可见,您可以节省不必要的油漆。请注意隐藏控件与禁用控件的效果。仍会绘制已禁用的控件。

    • 虽然它不会影响渲染速度,但如果您有任何闪烁,我会查看double buffering。使用从 XP 开始引入的 WS_EX_COMPOSITED 标志(据报道也适用于 Windows 8),这将确保表单 它的控件的双缓冲。它包含在这个问题中:Winforms Double Buffering

    【讨论】:

    • 我知道 WinForm 中的句柄我不知道 WPF 每个窗口使用一个句柄。我试试看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2015-06-30
    • 2021-09-04
    相关资源
    最近更新 更多