当调整拥有大量控件的窗口的大小时,WPF性能问题

5
我有一个包含精美图像以及约200个控件(派生自按钮)的WPF窗口,它们中的所有控件都使用我的5个模板之一(路径、阴影效果等)。可以肯定,这是一个需要大量绘制的窗口。我可以接受这样。
我的问题来自于调整窗口大小。最大化/还原需要1-2秒钟,但手动拖动左下角会导致系统挂起5-10秒钟。在这段时间内,窗口为黑色并且只显示部分残留物直到最终结果被显示。这看起来很业余,而我无法接受。
远程连接: 使用远程帐户,我发现窗口调整大小始终需要1-2秒钟,但在我拖动窗口边框时不会绘制"中间"阶段。结果与我期望的一样顺畅。
我的结论是:在调整大小期间 重绘 是瓶颈。
不可避免的问题是:我该如何避免在调整大小完成之前重绘窗口?
提前感谢您的任何想法...

虽然你有200个控件,这并不好,但这是一个好问题。 :) - Tim Lloyd
谢谢 ;) 这听起来像是糟糕的设计,但实际上它是一个非常复杂的接口。可以说是火箭科学。 - Seb
不可避免的问题是:如何在调整大小完成之前防止窗口重新绘制?- 远程桌面;-) - Firoso
不错的尝试,Firoso ;) 但我的接口已经是使用实际硬件仪器的“远程”解决方案...我开始认为WPF并不适用于超过2-3个控件的界面。像简单的配置对话框。有人愿意证明我错吗?我很乐意被纠正! - Seb
3个回答

4

@Seb: 我开始觉得WPF不适合超过2-3个控件的界面

Visual Studio 2010和Expression Blend应该是很好的反例。尽管Visual Studio有时会冻结,但瓶颈绝对不在WPF渲染中。

@Seb: 不可避免地会有这样一个问题:如何在调整大小完成之前防止窗口重新绘制?

只需在调整大小/最大化之前将窗口内容的可见性设置为Visibility.Collapsed,然后在之后再将其设置为可见。虽然我认为你问错了问题。以下才是正确的问题:

如何使我的控件测量/排列极快?

要回答这个问题,您需要查看代码。也许您在测量/排列算法中密集使用依赖属性?或者您选择了错误的面板(例如,Grid比Canvas慢)?或者...我就不猜了 :)

顺便说一下,最好在分析器下启动应用程序并证明瓶颈而不是假设可能出现的位置。检查Eqatec Profiler它是免费但足够强大。VS 2010也提供了不错的分析功能,尽管它远非免费。您可能还想查看WPF Performance Suite

希望这可以帮助到您。


好的。终于成功尝试了你的方法。我们正在隐藏一些昂贵的层,这非常有帮助。我认为我们正在推动WPF到极限......从我听到的消息来看,dotnet 4&msdev 2010&blend 4可能具有我们从dotnet 3.5&msdev 2008&blend 3中没有获得的优化。我们会到达那里的。感谢您的输入! - Seb

1

让我知道这个是如何工作的... 我假设你的根视觉元素正在水平和垂直方向上拉伸以填充具有自动高度/宽度的窗口。去掉自动高度/宽度。在应用程序启动时设置根元素的尺寸。有一个FrameworkElements有一个size changed event。在你的Application.Current.MainWindow上注册这个事件(可能是一个打字错误,那是从记忆中得出的)。每当这个事件触发时,就启动一个带有小间隔的计时器。如果在计时器运行时再次调整大小,则忽略它并重置计时器。一旦计时器触发,你现在知道用户想要的新尺寸,并且他们已经(至少短时间内)停止调整窗口大小。

希望这能帮到你!


很好的解决方法,但在调整大小时我们需要至少展示一些内容,否则用户不会知道最终结果是什么,直到他释放鼠标... 我会记住这个方法。它可能在某一天证明是一个有用的解决方法。非常感谢。 - Seb

0
Ragepotato的答案和您关于需要在调整大小时大致看到接口外观的评论中,只要您的对象不会动态重新定位(如Wrap Panel)- 您可以拍摄窗口内容的屏幕截图并用它来填充您的框架。
将其设置为同时拉伸高度和宽度,您将获得一个(略微模糊的)特定大小的想法。虽然在调整大小时它不会实时更新,但在那几秒钟内可能并不重要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接