关于ControlTemplate 2

(参考自 ding.li)

WPF中有三大模板ControlTemplate,DataTemplate,ItemsPanelTemplate。

ControlTemplate和ItemsPanelTemplate是控件模板(用来描述控件本身的样式)

 

ControlTemplate(DataTemplate是数据模板(描述控件内部数据的样式)

ControlTemplate:控件模板主要有两个重要属性:VisualTree内容属性和Triggers触发器。所谓VisualTree(视觉树),就是呈现我们所画的控件。Triggers可以对我们的视觉树上的元素进行一些变化。一般用于单内容控件。、

  • 定义模板(在任何UserControl或者Resource下):
View Code
<Style TargetType="Button">

            <Setter Property="Template">

                <Setter.Value>

                    <ControlTemplate TargetType="Button">

                        <Grid>

                            <Ellipse Width="100" Height="100">

                                <Ellipse.Fill>

                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                                        <GradientStop Offset="0" Color="blue"/>

                                        <GradientStop Offset="1" Color="LightBlue"/>

                                    </LinearGradientBrush>

                                </Ellipse.Fill>

                            </Ellipse>

                            <Ellipse Width="80" Height="80">

                                <Ellipse.Fill>

                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                                        <GradientStop Offset="0" Color="White"/>

                                        <GradientStop Offset="1" Color="Transparent"/>

                                    </LinearGradientBrush>

                                </Ellipse.Fill>

                            </Ellipse>

                        </Grid>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>
  • 在MainWindows下call 模板
    1 <Button Content="Hello WPF"/>

    结果为:image

     
    ControlTemplate之子 ContentControl和ContentPresenter

    我们在ControlTemplate中画了两个椭圆,应用于所有的Button按钮(因为没有加x:key给模板),但我们Button中有Content属性(内容为 Hello WPF),却没有显示出来。因为这里用ControlTemplate重写了Button的样式,所以我们也要在ControlTemplate中增加 ContentControl。通过ContentControl中的Content来绑定父容器的Content属性。

 

  • 为ContentControl属性赋值
View Code
 1 <Style TargetType="Button">
 2             <Setter Property="Template">
 3                 <Setter.Value>
 4                     <ControlTemplate TargetType="Button">
 5                         <Grid>
 6                             <Ellipse Width="100" Height="100">
 7                                 <Ellipse.Fill>
 8                                     <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
 9                                         <GradientStop Offset="0" Color="blue"/>
10                                         <GradientStop Offset="1" Color="LightBlue"/>
11                                     </LinearGradientBrush>
12                                 </Ellipse.Fill>
13                             </Ellipse>
14                             <Ellipse Width="80" Height="80">
15                                 <Ellipse.Fill>
16                                     <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
17                                         <GradientStop Offset="0" Color="White"/>
18                                         <GradientStop Offset="1" Color="Transparent"/>
19                                     </LinearGradientBrush>
20                                 </Ellipse.Fill>
21                             </Ellipse>
22                             <ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/>
23                         </Grid>
24                     </ControlTemplate>
25                 </Setter.Value>
26             </Setter>
27         </Style>

这下内容出来了image

 

我们来看一下,ContentControl继承于Control的,用MSDN的话是:表示包含单项内容的控件、ContentControl 可以包含任何类型的公共语言运行库对象。如下ContentControl类图。

image

为了提高性能,我们可以用一个ControlPresenter来代替ContentControl,效果还是一样,那他们有什么区别呢?

来看下ControlPresenter这个类,它继承于FreameworkElement,如下图:

image

 

ControlPresenter 通常叫做内容占位符。所以我们可以看到

<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>来代替<ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/> 这里少了Content绑定父容器,因为ControlPresenter有个隐式的Content="{TemplateBinding Content}"。

从他们的基类可以看出,ContentControl比ContentPresenter大多了。

其实ControlPresenter是一个原始的构建块,而ContentControl是一个带控件模板的成熟控件(里面包含ControlPresenter)。

一般用ControlPresenter。

 

ControlTemplate的VisualTree我们讲过了,下面看下他的trigger如何运用。

 

我们在原来的代码中增加IsMouseOver事件

 

<ControlTemplate.Triggers>

             <Trigger Property="IsMouseOver" Value="true">

                   <Setter TargetName="ellipse1" Property="Fill" Value="Red"/>

             </Trigger>

 </ControlTemplate.Triggers>

 

当我们把鼠标移上去的时候就会变成如下图所示:

 

image

 

发挥我们的想象力,我们可以根据ControlTemplate做更多的特效。如下

 

View Code
 1 <Style TargetType="CheckBox">
 2 
 3             <Setter Property="Template">
 4 
 5                 <Setter.Value>
 6 
 7                     <ControlTemplate TargetType="CheckBox">
 8 
 9                         <DockPanel>
10 
11                             <ContentPresenter DockPanel.Dock="Left" VerticalAlignment="Center" />
12 
13                             <Grid>
14 
15                                 <Grid.ColumnDefinitions>
16 
17                                     <ColumnDefinition Width="30"/>
18 
19                                     <ColumnDefinition Width="30"/>
20 
21                                 </Grid.ColumnDefinitions>
22 
23                                 <Rectangle Grid.Column="0" Grid.ColumnSpan="2" Fill="Gray"/>
24 
25                                 <TextBlock x:Name="txtBox"  Foreground="White" />
26 
27                             </Grid>
28 
29                         </DockPanel>
30 
31                         <ControlTemplate.Triggers>
32 
33                             <Trigger Property="IsChecked" Value="True">
34 
35                                 <Setter TargetName="txtBox" Property="Grid.Column" Value="1"/>
36 
37                                 <Setter TargetName="txtBox" Property="Text" Value="On"/>
38 
39                                 <Setter TargetName="txtBox" Property="Background" Value="LightBlue"/>
40 
41                             </Trigger>
42 
43                             <Trigger Property="IsChecked" Value="{x:Null}">
44 
45                                 <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/>
46 
47                             </Trigger>
48 
49                             <Trigger Property="IsChecked" Value="false">
50 
51                                 <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/>
52 
53                                 <Setter TargetName="txtBox" Property="Text" Value="OFF"/>
54 
55                             </Trigger>
56 
57                         </ControlTemplate.Triggers>
58 
59                     </ControlTemplate>
60 
61                 </Setter.Value>
62 
63             </Setter>
64 
65         </Style>
66 
67 <Grid>
68 
69         <CheckBox Width="100" Height="30" Content="Click Me"/>
70 
71  </Grid>

 

 

效果图:点击之前image点击之后image

 

 

posted @ 2012-08-30 08:53  若愚Shawn  阅读(462)  评论(0编辑  收藏  举报