WPF:UserControl与CustomControl性能问题

5
从性能角度来看,用户控件和自定义控件哪一个更好? 目前我正在使用用户控件,在特定的场景下,我创建了大约200个不同实例的控件,但加载速度有点慢,需要等待至少20-30秒才能完成操作。我该如何提高性能?
编辑: 场景如下: 在我的窗口中,我有一个TreeView,其中每个项表示不同的用户定义类型,因此我为每种类型定义了DataTemplate。这些DataTemplates使用用户控件,并且这些用户控件绑定了用户定义类型的属性。简单地说,TreeView映射了用户定义类型的分层数据结构。现在我从Xml中读取并创建分层结构,将其分配给TreeView,但加载时间很长。有任何帮助吗?

我认为无论是UserControl还是CustomControl都没有更高的性能,但老实说我不确定。你的控件在做什么?它由哪些元素组成?它如何获取数据?这些问题可能有助于解决性能问题。 - Ed Gonzalez
艾德是正确的。了解控件是否嵌套在其他位置或者是独立的窗口中也会很有帮助。希望你不是在Winforms应用程序中启动WPF窗口。 - Ragepotato
你的树是否使用VirtualizingPanel?这样做可以大大提高性能,因为您不需要一次加载所有用户控件。 - Ed Gonzalez
另一个需要检查的事情是你花费多少时间创建分层结构,以及将其放到屏幕上需要多长时间。也许读取Xml并构建对象是你花费大部分时间的地方。如果是这种情况,那么VirtualizingPanel帮助不大。 - Ed Gonzalez
5个回答

6
我有一个应用程序,需要加载大约500个小控件。我们最初将它们构建为用户控件,但似乎加载baml会使控件加载缓慢(每个控件都非常快,但当我们达到300个时,它们所有的总和似乎会累加)。用户控件似乎还使用了大量内存。我们将这些控件切换为自定义控件后,应用程序启动速度几乎快了一倍,占用的内存也只有原来的三分之一。不是说这种情况总是如此,但是对于我们来说,自定义控件产生了很大的影响。

1
我也有同样的经验。加载许多小的UserControl的成本相当高,但是一旦将UserControl转换为自定义控件,这个成本似乎就消失了。我猜测在后一种情况下,昂贵的操作,如读取Baml和初始化大量的依赖属性只会执行一次,而不是每个实例都执行一次。 - Omer Raviv
自定义控件不能加载XAML? - GorillaApe
两者都可以加载XML,但根据@Omer Raviv的答案,似乎XAML(转换为BAML)只被读取一次并缓存,而不是一遍又一遍地读取。 - Michael Baer

2

@Ed 是的,你说得没错!但在我的情况下,我避免使用它(我将其设置为false),因为我需要通过代码选择一些TreeViewItem并将其聚焦。无论如何,感谢你的帮助,还有其他方法吗? - viky
这里有一篇文章 http://bit.ly/cZQdGy,其中有人试图在使用虚拟化TreeView时进行导航。那里链接了几个试探性的解决方案,也许可以将其中一个改造以帮助解决问题。 - Ed Gonzalez
这是我的博客文章,我最终找到了一种相当不错的虚拟导航方式,但它仍然感觉非常“hacky”。我很快会发布它。最终,我选择了另一种解决方案,而不是导航到项目,我允许用户通过更改CollectionView过滤器属性(绑定到视图模型中的属性)来筛选特定项目。我也会发布这种方法。抱歉我现在没有时间,但如果你只想要代码,我可以尝试为你提供gist。 - Chris Nicola

0

这是关于我在WPF虚拟化堆栈面板和TreeView中遇到问题的后续文章。希望这能对你有所帮助。

http://lucisferre.net/2010/04/21/virtualizing-stack-panel-wpf-part-duex/

长话短说:使用当前的VSP可以进行导航,但这有点像黑客行为。当前的VSP设计需要重新制定,因为它当前虚拟化视图的方式会打破视图和ViewModel之间的耦合关系,进而破坏整个MVVM概念。

0
在大量添加控件时,请确保使用SuspendLayout。在将控件添加到任何容器之前,尽可能完全配置控件。

我该怎么做?有任何例子吗? - viky
2
在WPF中不存在SuspendLayout。 - Maurizio Reginelli
@Maurizio:哎呀。TreeView和UserControl都是winforms类,这让我困惑了。但是没有SuspendLayout相当糟糕,因为在WPF中添加控件是触发重新布局的事情之一。而且UIControlCollection上也没有AddRange方法,无法避免重复的重新布局。也许先将子项添加到屏幕外的控件中,然后再将父项添加到窗口中,可能会导致单个的布局操作? - Ben Voigt

0
我曾在微软工作,由于其性能不佳,我们不允许使用UserControl。我们总是使用C#创建控件。我不确定DataTemplates的性能如何,但很想知道它是否更好。我怀疑它会更好一些。

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