语义的优势;他们知道你刚刚实例化了什么面板子类,在元素树里面它处于什么位置等。好好地综合基于工具的只列出基本的可能性的智能,然后学会按F1来获 取SDK页面的更多的帮助信息。这是我们追赶即将来临的工具/SDK的发行的下一步。限于篇幅,不能细细讲解。
没有XAML XSD的计划?
我以前在博客上写过这个。对一个像WPF这样有很多维的产品来说,XAML的计划很困难。但你也许已经注意到接下来的XAML综合技术(Workflow Foundation, Silverlight)确实包括了XSD类型的计划。说到WPF XAML的计划,我们仍然保持观望。 WPF图形系统 【IT168 技术文档】
在Windows NT中,图形多媒体系统基于层次结构。应用程序与顶层的API(实际上是多个用户模式的系统DLL,比如GDI32.DLL)交互,这些系统DLL最终会 通过系统服务调用处于内核模式的系统服务。NT系统的详细信息可参考《Windows 图形编程》的第一、二章。在Windows Vista中,图形系统已经移出了内核模式,并有自己的空间--WPF。 WPF移出内核除了全面提高稳定性(内核模式中通常需要共享资源),也使得实现内核模式高级控制成为可能。
首先,WPF不再唯一依靠GDI图形API,Vista更多的依靠Direct3D处理图形操作,这样允许更多的D3D特征,实现更酷的外观和效果。当 然,为了实现这样的效果,Vista的设计上也有所改变。Windows Vista尽量不用CPU进行显示,而是用显示卡的图形处理单元(Graphics Processing Unit, GPU),用矢量图代替位图。 Windows Vista还采用了另外一种驱动模型--Windows显示驱动模型(WDDM)。实现操作系统和图形卡GPU之间更复杂的通信。为了处理操作系统更高的3D处理请求,新的WDDM驱动类型需要更多的显示卡内存。Vista能尽可能的利用显示卡以达到最好的性能。
现在基本了解了Windows Vista图形系统,再看看其可测量性。Windows Vista可提供非常高的终端图形,据此很多人都错误的认为:为了运行Windows Vista操作系统,必须要非常高端的图形硬件。事实上并不完全如此。Windows Vista图形系统一个关键好处就是可以检测显示卡的性能。Vista根据不同的性能和驱动模型(WDDM,XPDM)提供给用户不同的用户体验。
在Windows NT中,图形多媒体系统基于层次结构。应用程序与顶层的API(实际上是多个用户模式的系统DLL,比如GDI32.DLL)交互,这些系统DLL最终会 通过系统服务调用处于内核模式的系统服务。NT系统的详细信息可参考《Windows 图形编程》的第一、二章。在Windows Vista中,图形系统已经移出了内核模式,并有自己的空间--WPF。
WPF移出内核除了全面提高稳定性(内核模式中通常需要共享资源),也使得实现内核模式高级控制成为可能。首先,WPF不再唯一依靠GDI图形API, Vista更多的依靠Direct3D处理图形操作,这样允许更多的D3D特征,实现更酷的外观和效果。当然,为了实现这样的效果,Vista的设计上也 有所改变。Windows Vista尽量不用CPU进行显示,而是用显示卡的图形处理单元(Graphics Processing Unit, GPU),用矢量图代替位图。
Windows Vista还采用了另外一种驱动模型--Windows显示驱动模型(WDDM)。实现操作系统和图形卡GPU之间更复杂的通信。为了处理操作系统更高的 3D处理请求,新的WDDM驱动类型需要更多的显示卡内存。Vista能尽可能的利用显示卡以达到最好的性能。 WPF性能优化点 【IT168 技术文档】
在建立漂亮UI的同时,我们还需要关注应用程序的性能,WPF尤其如此。下面从MS的文档中总结出了一些有用的性能优化点。在实际编写的过程中,可以参考。这个Post非完全原创,是根据一些文档总结出来的。
1、建立逻辑树的时候,尽量考虑从父结点到子结点的顺序构建。因为当逻辑树的一个结点发生变化时(比如添加或删除),它的父结点和所有的子结点都会激发Invalidation。我们应该避免不必要的Invalidation。
2、当我们在列表(比如ListBox)显示了一个CLR对象列表(比如List)时,如果想在修改List对象后,ListBox也动态的反映这种变 化。此时,我们应该使用动态的ObservableCollection对象绑定。而不是直接的更新ItemSource。两者的区别在于直接更新 ItemSource会使WPF抛弃ListBox已有的所有数据,然后全部重新从List加载。而使用ObservableCollection可以避 免这种先全部删除再重载的过程,效率更高。
3、在使用数据绑定的过程中,如果绑定的数据源是一个CLR对象,属性也是一个CLR属性,那么在绑定的时候对象CLR对象所实现的机制不同,绑定的效率也不同。
A、数据源是一个CLR对象,属性也是一个CLR属性。对象通过TypeDescriptor/PropertyChanged模式实现通知功能。此时绑定引擎用TypeDescriptor来反射源对象。效率最低。
B、数据源是一个CLR对象,属性也是一个CLR属性。对象通过INotifyPropertyChanged实现通知功能。此时绑定引擎直接反射源对象。效率稍微提高。
C、数据源是一个DependencyObject,而且属性是一个DependencyProperty。此时不需要反射,直接绑定。效率最高。
4、访问CLR对象和CLR属性的效率会比访问DependencyObject/DependencyProperty高。注意这里指的是访问,不要和 前面的绑定混淆了。但是,把属性注册为DependencyProperty会有很多的优点:比如继承、数据绑定和Style。所以有时候我们可以在实现 DependencyProperty的时候,利用缓存机制来加速访问速度:看下面的缓存例子:
public static readonly DependencyProperty MagicStringProperty = DependencyProperty.Register(\typeof(string), typeof(MyButton), new PropertyMetadata(new PropertyInvalidatedCallback(OnMagicStringPropertyInvalidated),new GetValueOverride(MagicStringGetValueCallback))); private static void OnMagicStringPropertyInvalidated(DependencyObject d) { // 将缓存的数据标识为无效 ((MyButton)d)._magicStringValid = false; } private static object MagicStringGetValueCallback(DependencyObject d) { // 调用缓存的访问器来获取值 return ((MyButton)d).MagicString; } // 私有的CLR访问器和本地缓存 public string MagicString { get { // 在当前值无效时,获取最新的值保存起来 if (!_magicStringValid) { _magicString = (string)GetValueBase(MagicStringProperty); _magicStringValid = true; } return _magicString; } set { SetValue(MagicStringProperty, value); } } private string _magicString; private bool _magicStringValid; 另外,因为注册的DependencyProperty在默认是不可继承的,如果需要继承特性,也会降低DependencyProperty值刷新的效 率。注册DependencyProperty属性时,应该把DefaultValue传递给Register方法的参数来实现默认值的设置,而不是在构 造函数中设置。
5、使用元素TextFlow和TextBlock时,如果不需要TextFlow的某些特性,就应该考虑使用TextBlock,因为它的效率更高。
6、在TextBlock中显式的使用Run命令比不使用Run命名的代码要高。
7、在TextFlow中使用UIElement(比如TextBlock)所需的代价要比使用TextElement(比如Run)的代价高。
8、把Label(标签)元素的ContentProperty和一个字符串(String)绑定的效率要比把字符串和TextBlock的Text属性 绑定的效率低。因为Label在更新字符串是会丢弃原来的字符串,全部重新显示内容。
9、在TextBlock块使用HyperLinks时,把多个HyperLinks组合在一起效率会更高。看下面的两种写法,后一种效率高。
A、
11、在自定义控件,尽量不要在控件的ResourceDictionary定义资源,而应该放在Window或者Application级。因为放在控件中会使每个实例都保留一份资源的拷贝。
12、如果多个元素使用相同的Brush时,应该考虑在资源定义Brush,让他们共享一个Brush实例。
13、如果需要修改元素的Opacity属性,最后修改一个Brush的属性,然后用这个Brush来填充元素。因为直接修改元素的Opacity会迫使系统创建一个临时的Surface。
14、在系统中使用大型的3D Surface时,如果不需要Surface的HitTest功能,请关闭它。因为默认的HitTest会占用大量的CPU时间进行计算。 UIElement有应该IsHitTestVisible属性可以用来关闭HitTest功能。 WPF中的Style 【IT168 技术文档】
Style是一种修改属性值是方法。我们可以将其理解为对属性值的批处理。对批处理大家应该不会感到默认。对,通过Style我们可以批量修改属性的值。先从一个简单的Style例子开始:
定义后,引用这个特殊Style的CheckBox的代码是这样的: