提高WPF性能技巧分享

开发 开发工具
WPF性能的提高可以通过各种方法来实现。在这篇文章中我们就为大家总结了几种提高WPF性能的技巧方法,希望对大家有所帮助。

WPF的应用可以帮助我们实现许多基于图形界面方面的功能实现。不过在实际使用中,开发人员往往都追求更高性能的使用。在这里就介绍一下有关WPF性能的提高方法。#t#

在建立漂亮UI的同时,我们还需要关注应用程序的性能,WPF尤其如此。下面从MS的文档中总结出了一些有用的性能优化点。在实际编写的过程中,可以参考。这个Post非完全原创,是根据一些文档总结出来的。

1、建立逻辑树的时候,尽量考虑从父结点到子结点的顺序构建。因为当逻辑树的一个结点发生变化时(比如添加或删除),它的父结点和所有的子结点都会激发Invalidation。我们应该避免不必要的Invalidation。

2、当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避免这种先全部删除再重载的过程,WPF性能更高。

3、在使用数据绑定的过程中,如果绑定的数据源是一个CLR对象,属性也是一个CLR属性,那么在绑定的时候对象CLR对象所实现的机制不同,绑定的效率也不同。

A、数据源是一个CLR对象,属性也是一个CLR属性。对象通过TypeDescriptor/PropertyChanged模式实现通知功能。此时绑定引擎用TypeDescriptor来反射源对象。效率***。

B、数据源是一个CLR对象,属性也是一个CLR属性。对象通过INotifyPropertyChanged实现通知功能。此时绑定引擎直接反射源对象。WPF性能稍微提高。

C、数据源是一个DependencyObject,而且属性是一个DependencyProperty。此时不需要反射,直接绑定。效率***。

4、访问CLR对象和CLR属性的效率会比访问DependencyObject/DependencyProperty高。注意这里指的是访问,不要和前面的绑定混淆了。但是,把属性注册为DependencyProperty会有很多的优点:比如继承、数据绑定和Style。所以有时候我们可以在实现DependencyProperty的时候,利用缓存机制来加速访问速度:看下面的缓存例子:

  1. public static   
  2. readonly DependencyProperty 
    MagicStringProperty = DependencyProperty.
    Register("MagicString", typeof(string), 
    typeof(MyButton), new PropertyMetadata
    (new PropertyInvalidatedCallback(OnMagic
    StringPropertyInvalidated),new GetValue
    Override(MagicStringGetValueCallback)));   
  3. private static void OnMagicString
    PropertyInvalidated(DependencyObject d) {   
  4. // 将缓存的数据标识为无效   
  5. ((MyButton)d)._magicStringValid = false;   
  6. }   
  7. private static object MagicStringGet
    ValueCallback(DependencyObject d) {   
  8. // 调用缓存的访问器来获取值   
  9. return ((MyButton)d).MagicString;   
  10. }   
  11. // 私有的CLR访问器和本地缓存 public 
    string MagicString {   
  12. get {   
  13. // 在当前值无效时,获取***的值保存起来 if 
    (!_magicStringValid) {   
  14. _magicString = (string)GetValueBase
    (MagicStringProperty);   
  15. _magicStringValid = true;   
  16. }   
  17. return _magicString; }   
  18. set { SetValue(MagicString
    Property, value);   
  19. }   
  20. }   
  21. private string _magicString;   
  22. private bool _magicStringValid; 

另外,因为注册的DependencyProperty在默认是不可继承的,如果需要继承特性,也会降低DependencyProperty值刷新的效率。注册DependencyProperty属性时,应该把DefaultValue传递给Register方法的参数来实现默认值的设置,而不是在构造函数中设置。

5、使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高,可以提高WPF性能。

6、在TextBlock中显式的使用Run命令比不使用Run命名的代码要高。

7、在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高。

8、把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。

9、在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。看下面的两种写法,后一种效率高。

A

  1. < TextBlock Width="600" >   
  2. < Hyperlink TextDecorations="None">
    MSN Home< /Hyperlink> < /TextBlock>   
  3. < TextBlock Width="600" >   
  4. < Hyperlink TextDecorations="None">
    My MSN< /Hyperlink> < /TextBlock> 

B

  1. < TextBlock Width="600" >   
  2. < Hyperlink TextDecorations="None">
    MSN Home< /Hyperlink> 
    < Hyperlink TextDecorations="None">
    My MSN< /Hyperlink> < /TextBlock> 

 10、任与上面TextDecorations有关,显示超链接的时候,尽量只在IsMouseOver为True的时候显示下划线,一直显示下划线的代码高很多,以提高WPF性能。

11、在自定义控件,尽量不要在控件的ResourceDictionary定义资源,而应该放在Window或者Application级。因为放在控件中会使每个实例都保留一份资源的拷贝。

12、如果多个元素使用相同的Brush时,应该考虑在资源定义Brush,让他们共享一个Brush实例。

13、如果需要修改元素的Opacity属性,***修改一个Brush的属性,然后用这个Brush来填充元素。因为直接修改元素的Opacity会迫使系统创建一个临时的Surface。

14、在系统中使用大型的3D Surface时,如果不需要Surface的HitTest功能,请关闭它。因为默认的HitTest会占用大量的CPU时间进行计算。UIElement有应该IsHitTestVisible属性可以用来关闭HitTest功能。

责任编辑:曹凯 来源: IT168
相关推荐

2009-12-23 14:30:24

WPF显示动态GIF

2009-12-24 09:38:27

WPF用户线程

2009-12-29 11:01:46

WPF淡入效果

2009-12-28 10:40:13

WPF调用Winfor

2009-12-09 17:33:22

PHP性能优化

2009-12-25 10:11:46

WPF后台控制动画

2010-02-23 16:46:47

WCF并发能力

2009-12-23 10:29:01

WPF应用程序

2017-11-06 13:25:25

MySQL数据库技巧

2009-06-17 10:13:03

提高EJB性能

2011-06-28 13:56:43

JAVA

2017-02-05 17:33:59

前端优化Web性能

2013-01-08 16:05:23

Android开发布局ViewStub

2020-09-23 09:20:58

代码Java字符串

2011-06-09 16:14:14

2011-07-05 14:59:17

java

2024-10-25 15:48:21

GPUPyTorch编程

2023-02-21 14:55:40

React开发技巧

2022-01-09 23:06:39

JavaScript

2009-12-25 17:39:01

WPF验证
点赞
收藏

51CTO技术栈公众号