WPF性能优化经验总结
创始人
2024-06-18 01:21:32
0

开发人员在使用WPF做图形界面的时候,通常都希望能有一个高效的利用率。在这里我们就为大家介绍一下有关WPF性能优化的几种方法。#t#

WPF性能优化一、Rendering Tier

1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染。下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tier 2的情况下也不会硬件加速。(不全,其余请查阅SDK)

Bitmap effects, Printed content, Tiled content that uses TileBrush, Layered windows.

下列情况为Layered window: 1. WindowStyle = none, 2.AllowsTransparency = true, 3.Background = Transparent.

WPF性能优化二、布局和设计

1.尽量多使用Canvas等简单的布局元素,少使用Grid或者StackPanel等复杂的,越复杂性能开销越大。

2.建立逻辑树或者视觉树的时候,遵循Top-Down的原则。示例代码如下:

 

  1. C#   
  2. private void OnBuildTreeTopDown
    (object sender, RoutedEventArgs e)  
  3. {  
  4. TextBlock textBlock = new TextBlock();  
  5. textBlock.Text = "Default";  
  6. DockPanel parentPanel = new DockPanel();  
  7. DockPanel childPanel;  
  8. myCanvas.Children.Add(parentPanel);  
  9. myCanvas.Children.Add(textBlock);  
  10. for (int i = 0; i <  150; i++)  
  11. {  
  12. textBlock = new TextBlock();  
  13. textBlock.Text = "Default";  
  14. parentPanel.Children.Add(textBlock);  
  15. childPanel = new DockPanel();  
  16. parentPanel.Children.Add(childPanel);  
  17. parentPanel = childPanel;  
  18. }  

 

WPF性能优化三、图像

1. 对Image做动画处理的时候(如调整大小等),可以使用这条语句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality),以改善性能。

2. 用TileBrush的时候,可以CachingHint。

WPF性能优化四、对象行为

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


 

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

 

 

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

 

WPF性能优化五、应用程序资源

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

2. 尽量使用Static Resources,但不能盲目使用。

WPF性能优化六、文本

1. 文字少的时候用TextBlock或者label,长的时候用FlowDocument.

2. 使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高。

3. 在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高.在FlowDocument中尽量避免使用TextBlock,要用Run替代。代码如下:

 

  1. < FlowDocument> 
  2. < !-- Text content within 
    a Run (more efficient). --> 
  3. < Paragraph> 
  4. < Run>Line one< /Run> 
  5. < /Paragraph> 
  6. < !-- Text content within 
    a TextBlock (less 
    efficient). --> 
  7. < Paragraph> 
  8. < TextBlock>Line two
    < /TextBlock> 
  9. < /Paragraph> 
  10. < /FlowDocument> 

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

 

  1. < !-- Run is used to set 
    text properties. --> 
  2. < TextBlock> 
  3. < Run FontWeight="Bold">
    Hello, world< /Run> 
  4. < /TextBlock> 
  5. < !-- TextBlock is used 
    to set text properties, 
    which is more efficient. --> 
  6. < TextBlock FontWeight=
    "Bold"> 
  7. Hello, world  
  8. < /TextBlock> 

 

5. 把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。如果字符串不需要更新,用Label就无所谓性能问题。

6. 在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。

 

  1. < !-- Hyperlinks in separate 
    TextBlocks. --> 
  2. < TextBlock> 
  3. < Hyperlink TextDecorations=
    "None" NavigateUri="http:
    //www.msn.com">MSN Home
    < /Hyperlink> 
  4. < /TextBlock> 
  5. < TextBlock Text=" | "/> 
  6. < TextBlock> 
  7. < Hyperlink TextDecorations=
    "None" NavigateUri="http:
    //my.msn.com">My MSN< /Hyperlink> 
  8. < /TextBlock> 
  9. < !-- Hyperlinks combined 
    in the same TextBlock. --> 
  10. < TextBlock> 
  11. < Hyperlink TextDecorations=
    "None" NavigateUri="http:
    //www.msn.com">MSN Home< /Hyperlink> 
  12. < Run Text=" | " /> 
  13. < Hyperlink TextDecorations=
    "None" NavigateUri="http:
    //my.msn.com">My MSN< /Hyperlink> 
  14. < /TextBlock> 

7. 显示超链接的时候,尽量只在IsMouseOver为True的时候显示下划线,一直显示下划线的代码高很多

8. 尽量不使用不必要的字符串连接。

WPF性能优化七、数据绑定

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

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

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

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

2.当一个CLR对象很大时,比如有1000个属性时,尽量把这个对象分解成很多很小的CLR对象。比如分成1000个只有一个属性的CLR对象。

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

4. 尽量绑定IList而不是IEnumerable到ItemsControl。

WPF性能优化八、其它性能建议

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

2. 用NavigationWindow的时候,尽量Update the client area by object,而不是URI

3. 尽量不要使用ScrollBarVisibility=Auto

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...