WPF学习心得(2)
模板
首先声明,我这里所说的模板,专指WPF中的控件模板(ControlTemplate),而其它的一些模板,如数据模板(DataTemplate)等不在本文的讨论范畴。
模板适用于这样一种场合:控件在功能上满足程序的要求,但界面上不能(或不方便)满足程序的要求,比如说:我们更改一个控件的外观,都是基于其已有的属性——要更改其背景色,设置Background属性;要更改其高度,设置其Heigth属性……如果一个控件没有提供相应的属性,则无法进行处理,比如现在需要一个椭圆按钮,由于Button上并没有提供相关的属性,则我们不能够(至少是不方便)通过设置其属性来实现我们的要求。在这种情形下,控件模板应运而生。
示例代码如下:
<Window x:Class="WpfApplication30.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="btnTemplate" TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Button Background="Gray" Content="I am a Button !" Margin="42,21,50,131">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<Button Margin="42,145,50,12" Background="Gray" Template="{StaticResource btnTemplate}">I am a Button !</Button>
</Grid>
</Window>
我们来看看模板的定义:
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
这里创建了一个ControlTemplate的实例,并指定其TargetType属性为Button,表示该模板适用于按钮。
我在模板中放入了一个Grid以承载其它控件,Grid里可以放入任何控件,就像你在其它地方使用的时候一样,这里我挑了两个有特别意思的加以说明:
1.<Ellipse Fill="{TemplateBinding Background}"/>
你可以在模板中指明所有的属性,然后将该模板套用到多个对像上,但是,你会发现:这些对像都是一个模子刻出来的,完全一样,这可能不是你的初衷,因为你可能希望这些对象的外观一致,但是背景色不同。你虽然设置了Background属性,但是你会发现,这根本没起作用。
要实现这个目的,你需要使用模板绑定TemplateBinding,以上面为例,它告诉程序,椭圆的填充色要绑定到适用模板的对象的Background属性上。
2.<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
ContentPresenter对象对于ContentControl来说是必要的,它告诉程序如何呈现其Content属性,这里是居中显示,如何你不指定ContentPresenter对象,Content属性将无法显示。
总结:这里我用两种不同的方式来展示模板的使用——直接在控件的Template属性中定义及在资源中定义,可以看出,其效果是一样的。而实际上,更多的时候,我们会采用第三种方式:在样式里使用模板,这种方式我将会在样式那一章里再来写。