吴佳鑫的个人专栏

当日事当日毕,没有任何借口

导航

silverlight style和template 使用之tip

Style:

1、 Control Style

这是最基本的样式---控制样式,包括SL自带的控件和自定义控件。

•TargetType: Button    -- SL自带的控件
  TargetType: local:MyControl  -- 自定义的控件。 local是命名空间。
View Code
        <Style x:Key="ButtonStyle1" TargetType="Button">
            <Setter Property="Background" Value="#FF1F3B53"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
                                            <ColorAnimation Duration="0" To="#F2FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                            <ColorAnimation Duration="0" To="#CCFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                            <ColorAnimation Duration="0" To="#7FFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimation Duration="0" To="#FF6DBDD1" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundAnimation"/>
                                            <ColorAnimation Duration="0" To="#D8FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                            <ColorAnimation Duration="0" To="#C6FFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                            <ColorAnimation Duration="0" To="#8CFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                            <ColorAnimation Duration="0" To="#3FFFFFFF" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" Storyboard.TargetName="BackgroundGradient"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="FocusStates">
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unfocused"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="White" CornerRadius="3">
                                <Grid Background="{TemplateBinding Background}" Margin="1">
                                    <Border x:Name="BackgroundAnimation" Background="#FF448DCA" Opacity="0"/>
                                    <Rectangle x:Name="BackgroundGradient">
                                        <Rectangle.Fill>
                                            <LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
                                                <GradientStop Color="#FFFFFFFF" Offset="0"/>
                                                <GradientStop Color="#F9FFFFFF" Offset="0.375"/>
                                                <GradientStop Color="#E5FFFFFF" Offset="0.625"/>
                                                <GradientStop Color="#C6FFFFFF" Offset="1"/>
                                            </LinearGradientBrush>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Grid>
                            </Border>
                            <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            <Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="3" RadiusX="3"/>
                            <Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

 

另外用Setter来包含很多属性的设置,

•Setters:  Property, Value
 
 注意:Template也是style中的一个 setter. 
 
 
 比较特殊的sytle:
 
–关于ItemContainerStyle
•TargetType: ListBoxItem
一个ListBox是由一个一个ListBoxItem来组成的,每一个ListBoxItem它的模板它的样式就是通过ItemContainerStyle去定制。所以ItemContainerStyle 的 TagetType 是一个 ListBoxItem。
 
下面以一个图片来看style所包含的范围:

 

 可以看出, ItemTemplate 只是 ItemContainerStyle 中的一员。

ListBoxItem 是由其中一个ItemContainerStyle 来组成的,是组合的关系。

ContentPresenter 是由一个或0个DataTemplate来组成的。

为什么是0个或1个呢,因为如果是0个的时候,那么 ContentPresenter 就会用默认的方式来展现,如果是1个的时候,那就是会用具体的 DataTemplate去展现。

 

另外,ItemContainerStyle 还会有其它的特性,比如说TabNavigation。

•TabNavigation: Local, Cycle, Once
这个属性是比较特殊的属性,当它设成Local或Once的时候,那么我们用Tab键来切换页面中不同的控件的时候,当焦点走到ListBox里面时候,会跳到里面一个一个Item地进行切换。如果设成Cycle的时候,那它就不会一个一个Item切换。
 
 
 
下面讲解几个关于DataGrid的style.
在blend中拖放一个datagrid,我们可以看到有这么多的sytle

先上一张UML图

上图可以看过,一个datagrid 是由一个或多个DataGridColumn 和 一个或多个的DataGridRow组成。

然后一个DataGridColumn 会有一个 DataGridColumnHeader。而一个DataGridRow 它会有一个DataGridRowHeader , DataGridCellsPresenter , DataGridDetailsPresenter 这三来一起组成一行的DataGridRow。

 

1、ColumnHeaderStyle  这是每一列的 列头样式。

这一个style对应的是  DataGridColumnHeader 这个控件的样式。 我们可以在blend中拖出这个控件。

实际上这个 Header 它本身就是一个控件,我们可以和datagrid一样拉出来放在界面上。它是被组合到DataGrid里面的。

我们编辑的DataGrid  的 ColumnHeaderStyle 样式,实际上就是在编辑DataGridColumnHeader这个控件的样式。

可以从XAML代码见证这一点:

<Style x:Key="DataGridColumnHeaderStyle" TargetType="dataPrimitives:DataGridColumnHeader">

</Style>

这个样式特殊的一些属性:

Separator:两个header之间,会对应一个分隔线,我们可以设置SeparatorBrush, SeparatorVisibility

 

2、RowStyle

这一个style对应的是DataGridRow 这个控件的样式 ,可们可以在blend中拖出这个控件。

实际上这个 Row 它本身就是一个控件 , 可以可以和datagrid一样拉出来放在界面上。它是被组合到DataGrid里面的。

我们编辑的DataGrid 的 DataGridRow 样式,实际上就是在编辑 DataGridRow 这个控件的样式。

可以从XAML代码见证这一点:

<Style x:Key="DataGridRowStyle" TargetType="data:DataGridRow"></Style>

 上面说到,一个DataGridRow 它会有一个DataGridRowHeader , DataGridCellsPresenter , DataGridDetailsPresenter 这三来一起组成一行的DataGridRow。

我们来一个图看看它包含的三个是怎么样的范围。

 

 可以看到,红色框住的范围,就是一个DataGridRow,也就是说是一条记录。包括了蓝色框所指的DataGridRowHeader,包括绿色框所指的DataGridCellsPresenter,包括紫色框所指的DataGridDetailsPresenter。也就是说一条记录包括了这三块的内容。

在blend中可以见证,我们在blend中拖出一个datagrid,编辑datagrid的 DataGridRow样式,如下图:

 

 

在blend中,模板中可以看到 RowHeader, CellsPresenter , DetailsPresenter 这三个东西,也就是上面所说的三个东东。

比较特殊的属性:

•DetailsTemplate  (下面再说明这个模板)
•Header, HeaderStyle
 
 
3、CellStyle

 

这一个style对应的是DataGridCell 这个控件的样式 ,可们可以在blend中拖出这个控件。

实际上这个 DataGridCell 它本身就是一个控件 , 可以可以和datagrid一样拉出来放在界面上。它是被组合到DataGrid里面的。

我们编辑的DataGrid 的 DataGridCell 样式,实际上就是在编辑 DataGridCell这个控件的样式。也就是一个单元格的样式。

可以从XAML代码见证这一点:

<Style x:Key="DataGridCellStyle" TargetType="data:DataGridCell"></Style>

下面来一个图片看一下它的范围

实际就是datagrid里面一个单元格。

它里面的内容,有一个ContentControl,也就是我们的单元格默认要展现一些数据,是放在ContentControl中去展现的。

 

 

 

Template:

style与template是包含与被包含的关系, style中有其中一项设置就是设置template的。就是说style包含了template。

很多时候,我们不需要去编辑一个控件的很多样式(像字体大小、颜色等),只需要去编辑控件的一个模板,去编辑它的外观。

所以Blend会有这样的一个功能  --》“编辑模板”。也就是单单对模板来配置。下面来一个图看看:

 

下面介绍几种Template:

1、ControlTemplate (Basic)

2、ItemTemplate, ItemPanel

3、RowDetailsTemplate

 

1、ControlTemplate:

使用得最多的,对一个控件的模板的外观的定制。

它跟style一样,也可以针对两个Target。一种是内置的控件,一种是自定义的控件。

•TargetType: Button    -- SL自带的控件
  TargetType: local:MyControl  -- 自定义的控件。 local是命名空间。

<ControlTemplate TargetType=“Button">

  <Grid x:Name=“RootElement“/>   <!--Single Child-->

</ControlTemplate >

 同时这也是一个最特殊的,也是SL中唯一 一个不能在后置C#代码中创建的!

 

2、ItemTemplate, ItemPanel

A.这两个是对应一些列表控件来使用的,比如:ListBox , ComboBox 。

B.他们对应的Template 是DataTemplate, ItemsPanelTemplate。也就是说 ItemTemplate 是一个DataTemplate是元素的数据模板 ,  ItemPanel 是一个 ItemsPanelTemplate是元素容器的一个模板。

C.这两个和上面的ControlTemplate比较一下,可以知道 : ItemTemplate, ItemPanel是没有 TargetType 这一个属性的。

也就是说它们不是专门对应哪一个控件去做的。也就是说它是对它的父亲节点是一无所知,也就是说,是谁使用了这个模板,他自己并不知道,并不像上面的ControlTemplate这样的,假如我们在一个Grid里面,我们想要对他的父亲的某个属性做绑定,我们可以使用TemplateBinding这样的方式去绑定父亲节点的属性,但是我们的ItemTemplate, ItemPanel是做不到这一点的,那是因为他根本没有一个TargetType这样的一属性去指明它的父亲节点是一个button,还是一个checkbox,还是一个ListBox。同样的因为它不知道这些内容,所以它在绑定的时候,是需要我们手工地去写它绑定的一个方式。因为它根本不知道我们要绑定的数据会有一些什么属性,所以我们要自己很清楚的情况下去编写这样的代码。

D:在XAML的代码方式:

<DataTemplate x:Key="DataTemplate2"> 

  <!--No TargetType -->

  <Grid x:Name=“RootElement“/>   <!--Single Child-->

</DataTemplate >

 

<ItemsPanelTemplate x:Key="ItemsPanelTemplate1"> 

  <!--No TargetType -->

  <StackPanel Orientation=“Vertical"/>   <!--Single Child-->

</ItemsPanelTemplate>

可以看到,他需要指明一个Key,这并不像我们前面的ControlTemplate当指明了一个TargetType的时候它可以不指明key,因为默认情况下,一个button这些控件它会自己去找自已对应的模板。因为ItemTemplate, ItemPanel是没有TargetType的,所以这两个一定要指标一个Key,别人才可以去找到你,去使用你。

 

 

3、RowDetailsTemplate

A.和ItemTemplate一样,它是一个DataTemple(数据模板),也并不知道使用它的父亲是谁,(不需要指定TargetType)。

   这个模板是在DataGrid中使用。

B.与DataGridRowStyle 里面的DetailsTemplate区别:在DataGrid层次上的RowDetailsTemplate的优先级要比 DataGridRowStyle 里面的 DetailsTemplate要低。

  

posted on 2012-08-05 01:06  _eagle  阅读(1537)  评论(0编辑  收藏  举报