关于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

 

 

你可能感兴趣的:(template)