调整具有大量控件的窗口大小时的 WPF 性能问题
我有一个 WPF 窗口,其中包含一个精美的图像,其中包含大约 200 个控件(源自按钮),所有这些控件都使用我的 5 个模板之一(路径、阴影效果等)。同意,这是一个很难绘制的窗口。我可以忍受这一点。
我的问题来自于调整窗口大小。最大化/恢复大约需要 1-2 秒,但手动拖动左下角会导致系统挂起大约 5-10 秒。在这段延迟中,窗口是黑色的,并且是黑色的。包含部分剩余部分,直到显示最终结果。它看起来很业余,,我无法忍受。
远程连接:使用远程帐户,我发现窗口调整大小总是需要 1-2 秒,但在拖动窗口边框时不会绘制“中间”阶段。结果正如我所期望的那样迅速。
我的结论是:调整大小期间的重绘是瓶颈。
不可避免的问题是:如何防止重绘窗口,直到调整大小完成?
预先感谢您的任何想法...
I have a WPF window that contains a fancy image with roughly 200 controls (derived from buttons), all of which use one of my 5 templates (paths, shadow effects, etc). Agreed, it is a heavy window to draw. I can live with that.
My problem comes from resizing the window. Maximize/Restore take about 1-2 seconds, but manually dragging the bottom-left corner causes the system to hang for about 5-10 seconds. In that delay, the window is black & contains partial leftovers until the final result is shown. It looks amateurish and that, I can't live with.
Remote connection : using a remote account, I found that the window resize always takes 1-2 seconds, but doesn't draw the "intermediate" stages while I'm dragging the window borders. The result is as snappy as I would expect.
My conclusion is this: It's the redraws during the resize that are bottlenecks.
The inevitable question is this : how can I prevent redrawing the window until the resize is finished?
Thanks in advance for any ideas...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Visual Studio 2010 和 Expression Blend 应该是很好的反例。尽管 Visual Studio 有时会冻结,但瓶颈绝对不在 WPF 渲染中。
只需在调整大小/最大化之前将窗口的内容可见性设置为 Visibility.Collapsed 并使其可见即可。虽然我认为你问错了问题。这是正确的
如何使我的控件测量/排列速度极快?
要回答它,您应该看一下您的代码。也许您在测量/排列算法中大量使用依赖属性?或者也许您选择了错误的面板(例如,Grid 比 Canvas 慢)?或者也许......我在这里停止猜测:)。
顺便说一句,最好在分析器下启动您的应用程序并证明瓶颈,而不是假设它可能在哪里。检查 Eqatec Profiler,它是免费的,但功能足够强大。 VS 2010 还提供了很好的分析功能,尽管它远非免费。您可能需要检查WPF Performance Suite。
希望这有帮助。
Visual Studio 2010 and Expression Blend should be good counterexamples. Though Visual Studio sometimes freezes the bottleneck is definitely not in the WPF rendering.
Simply set the window's content visibility to
Visibility.Collapsed
before the resize/maximize and make it visible afterwards. Though I think you asked the wrong question. Here is the right oneHow to make my controls measure/arrange extremely fast?
And to answer it you should take a look at your code. Maybe you intensively use dependency properties in the measuring/arrange algorithm? Or maybe you picked wrong panels (e.g. Grid is slower than Canvas)? Or maybe... I stop guessing here :).
By the way, it's always better to launch your app under profiler and prove the bottleneck rather than assuming the place where it might be. Check Eqatec Profiler it's free yet powerful enough. VS 2010 also offers nice profiling features, though it's far from being free. And you may want to check WPF Performance Suite.
Hope this helps.
让我知道这是如何工作的...我假设您的根视觉项目正在水平和垂直拉伸,以自动高度/宽度填充您的窗口。摆脱自动高度/宽度。在应用程序启动时设置根元素的尺寸。有一个 FrameworkElements 有一个 尺寸改变事件。在您的
Application.Current.MainWindow
上注册(可能是拼写错误,这是我记忆中的)。每当此事件触发时,就以较小的间隔启动计时器。如果在计时器运行时再次调整大小,请忽略它并重置计时器。一旦计时器触发,您现在就知道用户想要的新大小,并且他们已经(至少在短时间内)停止调整窗口大小。希望有帮助!
Let me know how this works... I am assuming that your root visual item is stretching to horizontally and vertically to fill your window with auto height/width. Get rid of the Auto height/width. On app start up set the dimensions of the root element. There is a FrameworkElements have a size changed event. Register for this on your
Application.Current.MainWindow
(maybe be a typo, that was from memory). Whenever this event fires, start a timer with a small interval. If you get another resize while the timer is running, ignore it and reset the timer. Once the timer fires, you now know the new size the user desires and that they have (at least for a short period) stopped resizing the window.Hope that helps!
来自 Ragepotato 的回答 以及您关于需要在调整大小时大致了解界面的外观的评论,只要您没有让对象动态重新定位自身(例如
Wrap Panel) code>) - 您可以截取窗口内容的屏幕截图并用它填充框架。
将其设置为拉伸高度和宽度,您就会对特定尺寸有一个(稍微模糊的)想法。调整大小时它不会处于活动状态,但对于那几秒钟,这可能并不重要。
From Ragepotato's answer and your comment about needing to see roughly what the interface would look like while resizing, as long as you don't have your objects dynamically re-locating themselves (like a
Wrap Panel
) - you could take a screenshot of the window contents and fill your frame with it.Set it to stretch both height and width, and you'd get a (slightly fuzzy) idea of what a particular size would be. It wouldn't be live while resizing, but for those few seconds that probably wouldn't matter..