WPF控件是由纯粹的.net代码构成,以前的用户界面技术Windows窗体控件(封装了来自Win32API的核心要素,是不可改变的),因此WPF能提供样式和模版机制来允许用户进行修改。
1.理解逻辑树和可视化树
可视化树是逻辑树的扩展版本。如图,按钮也是由可视化元素组成,这些元素都是由FrameworkElement的派生类组成的
可以利用WPF UI分析工具Snoop进行分析窗口的可视化树
2.理解模板
模板提供了在可视化树中看到的扩展内容
模版类型包括:
1.控件模板(ControlTemplate):预先构建好控件,重写控件内容模型
2.数据模版(DataTemplate、HierarchicalDataTemplate):用于数据绑定,在已有控件的内部添加元素
3.面板模版(ItemsPanelTemplate ):特殊,较少使用,用于控制列表控件
将需要经常变更的控件属性提取出来整合进样式中,可以通过定义一个样式,在样式中设置模版属性(即样式关联模板)
主要通过添加触发器实现:
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="FocussCue" Property="Visibility" Value="Visible"/><!--显示焦点框-->
</Trigger>
</ControlTemplate.Triggers>
System.Windows.Controls.Primitives 包含原始的基本元素,Microsoft.Windows.Themes包含了用于渲染这些细节的基本绘图逻辑。
利用Template属性和XamlWrite类编写代码查看wpf原始控件的xaml模版
若使用Expression Blend,则可以如图直接查看
在定义资源时,可以将图像资源冻结:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:local="clr-namespace:CustomStyleAndTemplate">
<SolidColorBrush x:Key="PrimaryHueLightBrush" Color="{StaticResource Primary200}" po:Freeze="True" />
</ResourceDictionary>
在MSDN上看到,每一个SolidColorBrush占用的大小,当冻结的时候,需要212字节,未冻结的则需要972字节,即使单位很小,但是差距还是非常大的,通常我们写程序的时候,这类的对象都不会想到冻结它,当然,冻结的对象也意味着不能被修改,冻结等于只读。当SolidColorBrush当成资源对象的时候,这个对象几乎就是不会被修改的。所以,我们有必要在这种情况下将该对象冻结,以达到节省资源和优化程序的目的。克隆该对象,就相当于对当前对象的解冻行为。
xaml:
<SolidColorBrush x:Key="MyBrush" PresentationOptions:Freeze="True" Color="Red"/>
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
if (myBrush.CanFreeze)//如果可以冻结
myBrush.Freeze();//冻结对象,使之成为只读,提高性能
FreezableBtn.Background = myBrush;
if (myBrush.IsFrozen)//判断对象是否冻结
{
SolidColorBrush CloneBrush = myBrush.Clone();//如果是只读对象,则Clone对象
CloneBrush.Color = Colors.Red;
FreezableBtn.Background = CloneBrush;
}
else myBrush.Color = Colors.Red;//如果对象未被冻结,则可直接修改对象