我们刚刚将WinForms应用程序移植到WPF。 但是,性能急剧下降。
我们有一个用户界面,包含大约200个UserControl。 每个UserControl都由DataGrid(= 10列和3-15行)以及一个托管大约10个按钮的Panel定义。
它们都托管在ScrollViewer中。
(请不要建议更改UI。我对此没有任何影响。客户希望能够滚动到任何这些UserControl。)
由于我们将整个应用程序移植到WPF,启动时间增加了100%。使用WinForms,我们经历了15秒的启动时间,而现在,我们已经开始使用30秒。
您是否有任何建议或想法如何改善UI的加载时间,该UI由相同的UserControl组成,其中每个UserControl都绑定到不同的ViewModel? (也许有些快速克隆UserControl实例或者类似吗?)
我尽可能使用静态资源。 我尽可能避免网格和自动调整大小。
希望有人可以分享一些想法。
谢谢, TH
答案 0 :(得分:2)
答案 1 :(得分:2)
我的最终解决方案是自定义虚拟面板,它支持动态高度的项目。
有关如何创建虚拟面板的信息,请参阅http://rhnatiuk.wordpress.com/2006/12/13/implementing-a-virtualized-panel-in-wpf/。
我的UserControls支持两种状态: - 初始 - 加载
当应用程序处于空闲状态时,虚拟Panel会要求控件更改为“已加载”状态。这会加载昂贵的UserControl。
就像所有内容都是延迟加载的,只要用户停止滚动,就会加载可见的项目。
也许这有助于处于相同情况的其他人。 TH
答案 2 :(得分:0)
尝试仅创建当时可见的控件,使用延迟加载。
也许SnapsToDevicePixels=true
也可以帮助一点。
答案 3 :(得分:0)
伙计们,我考虑过以下实施。如果有人有疑虑请告诉我:
我将实现自己的虚拟化“StackPanel”,它支持平滑滚动。
目前我们假设UserControls的高度是固定的。一个页面可能包含5个UserControls。
然后我将继续缓存前面和后续页面:
在内存中,我将始终拥有15个UserControl。 ScrollViewer的内容是Canvas。 通过设置Canvas.Top来调整UserControls的位置。 让我们说现在的情况如下:
用户已滚动到第2页。 这意味着UserControl 5-9可见。现在用户向下滚动。 一旦UserControl 5变得不可见,我将使用顶部的UC(在本例中为UserControl 0),更改其ViewModel并调整其Canvas.Top,使其现在是ControlCollection结尾处的Control。 如果用户进一步滚动我使用UC 1,更改其ViewModel并调整其Canvas.Top。 等等。
此外,我将手动设置Canvas.Height,以便ScrollViewer以正确的方式表示ScrollBars。
我希望我的解释是可以理解的:)
您怎么看?
BR, TH
答案 4 :(得分:0)
我记得读过一些关于UserControl的每个实例如何加载资源字典的内容。因此,如果您描述的内容与您描述的一样多,则可能需要一段时间才能加载这些内容。
不幸的是我找不到我记得的链接,但这里有一个可能有用的链接: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c9b6aa9f-5a97-428c-8009-5cda432b820c
要尝试的另一件事是不使用UserControls而是使用DataTemplate来构建数据网格和按钮。或者为包含按钮的数据网格创建自定义控件模板。任何一个都可能更快。
希望这有帮助。