Sliverlight实例之 使用 ControlTemplate 自定义按钮的外观

按钮,最终效果,如下图:

 

见Project21_ButtonSkin

 

1, 创建Sliverlight项目

 

说明:

generic.xaml:样式和模板就被定义在这个文件里

MyButton.cs:控件的逻辑代码

 

2, 将下面两行代码添加到generic.xaml文件中

 

xmlns:src="clr-namespace:ButtonControlLibrary;assembly=ButtonControlLibrary"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"

 

 

 

3,Copy按钮的默认的ControlTemplate

 

(1)     在Blend for VS 中打开按钮的默认模板和样式

 

 

(2)     将(1)中的按钮“默认模板和样式”xaml代码,Copy到generic.xaml文件中

 

 

4,创建初始ControlTemplate 

(1)     删除 Setter 元素直到(但不包括)<Setter Property="Template">。

(2)     删除第一个 Grid 元素,但不删除它内部的元素。

(3)     删除所有 Storyboard 元素,包括它们内部的元素。

(4)     删除名为 Background 的 Border 元素,包括它内部的元素。

(5)     删除 ContentPresenter 元素。

(6)     删除名为 DisabledVisualElement 和 FocusVisualElement 的 Rectangle 元素。

Border、ContentPresenter 和 Rectangle 元素组成默认按钮控件的结构。

(7)     在 Style 元素中,将 TargetType 属性更改为 src:MyButton。

(8)     在 ControlTemplate 元素中,将 TargetType 属性更改为 src:MyButton。

 

 

5,在generic.xaml中,编辑自己的模板和样式

 

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
    xmlns:src="clr-namespace:ButtonControlLibrary;assembly=ButtonControlLibrary"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">

    <!--
    一,创建初始 ControlTemplate
    二,创建可视结构            step 1,2,3,4,5,6,7
    三,根据状态定义外观          step 8,9,10,11,12
    四,指定可视行为            step 13
    五,引用样式              step14
    -->
    <Style x:Key="ButtonStyle1" TargetType="src:MyButton" >    

        <!--step7 设置该按钮的默认属性-->
        <Setter Property="Background" Value="Navy"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Width" Value="100"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Margin" Value="10"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="src:MyButton">
                    <!-- step1 一个名为 RootElement 的 Border-->
                    <Border x:Name="RootElement">

                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <!--step13 使用 VisualTransition 可以指定控件转换为特定状态所耗费的时间。GeneratedDuration 属性指定转换所需的时间 -->
                                <vsm:VisualStateGroup.Transitions>
                                    <!--指定该按钮应经过百分之一秒才进入按下状态-->
                                    <vsm:VisualTransition To="Pressed" GeneratedDuration="0:0:0.01" />
                                    <!--指定该按钮应经过半秒才进入鼠标悬停状态-->
                                    <vsm:VisualTransition To="MouseOver" GeneratedDuration="0:0:0.5" />
                                    <!-- 指定该按钮应经过百分之一秒才从按下状态进入鼠标悬停状态-->
                                    <vsm:VisualTransition From="Pressed" To="MouseOver" GeneratedDuration="0:0:0.01" />

                                    <!-- 指定当控件从鼠标悬停状态转换为正常状态时某动画产生动作-->
                                    <vsm:VisualTransition From="MouseOver" To="Normal" 
                                      GeneratedDuration="0:0:1.5">
                                        <!-- 当用户将鼠标指针从按钮上移开时,按钮的边框在 1.5 秒内先变为蓝色,然后变为黄色,最后变为黑色-->
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames
                                                Storyboard.TargetProperty="Color"
                                                Storyboard.TargetName="BorderBrush"
                                                FillBehavior="HoldEnd" >
                                                <ColorAnimationUsingKeyFrames.KeyFrames>
                                                    <LinearColorKeyFrame Value="Blue" KeyTime="0:0:0.5" />
                                                    <LinearColorKeyFrame Value="Yellow" KeyTime="0:0:1" />
                                                    <LinearColorKeyFrame Value="Black" KeyTime="0:0:1.5" />
                                                </ColorAnimationUsingKeyFrames.KeyFrames>
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualTransition>

                                </vsm:VisualStateGroup.Transitions>

                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver">
                                    <!--step8 将鼠标指针移到按钮上方时,按钮边框会设为红色-->
                                    <Storyboard>
                                        <ColorAnimation Storyboard.TargetName="BorderBrush" 
                                            Storyboard.TargetProperty="Color" To="Red" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Pressed">
                                    <!--step9 当按钮处于按下状态时,按钮边框会设为透明-->
                                    <Storyboard >
                                        <ColorAnimation Storyboard.TargetName="BorderBrush" 
                                            Storyboard.TargetProperty="Color" To="Transparent"
                                        />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <!--step10 这使得当处于禁用状态时,DisabledRect 的 Opacity 会设为 1。这样将会在按钮的 IsEnabled 属性设置为 false 时显示 DisabledRect-->
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="DisabledRect" 
                                             Storyboard.TargetProperty="Opacity"
                                             To="1" Duration="0" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates">
                                <VisualState x:Name="Focused">
                                    <!--step11 -->
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" 
                                 Storyboard.TargetProperty="Visibility" Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>

                                </VisualState>
                                <VisualState x:Name="Unfocused">
                                    <!--step12 -->
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" 
                                 Storyboard.TargetProperty="Visibility" Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Collapsed</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <!--step2 按钮的背景-->
                        <Border.Background>
                            <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
                        </Border.Background>

                        <!--step3 作为 RootElement 的子级的 Grid-->
                        <Grid Background="{TemplateBinding Background}" Margin="4">
                            <!--step4 指示按钮是否具有焦点的 Rectangle-->
                            <Rectangle Name="FocusVisual" 
                                Visibility="Collapsed" Margin="2" 
                                Stroke="{TemplateBinding Foreground}" StrokeThickness="1" 
                                StrokeDashArray="1.5 1.5"/>
                            <!-- step5 一个显示按钮内容的 ContentPresenter-->
                            <ContentPresenter
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Margin="4,5,4,4" />
                            <!--step6 在禁用按钮时使按钮变灰的 Rectangle-->
                            <Rectangle x:Name="DisabledRect" 
                               Fill="#A5FFFFFF"
                               Opacity="0" IsHitTestVisible="false" />
                        </Grid>

                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <!-- step14 -->
    <Style TargetType="src:MyButton" BasedOn="{StaticResource ButtonStyle1}"></Style>


</ResourceDictionary>

 

 

6,使用自定义控件

 

在generic.xaml中,引用样式

 <!-- step14 -->
    <Style TargetType="src:MyButton" BasedOn="{StaticResource ButtonStyle1}"></Style>

 

 

在页面中,添加引用

xmlns:blib="clr-namespace:ButtonControlLibrary;assembly=ButtonControlLibrary"

 

 

在页面中,创建两个Button

<StackPanel>
        <blib:MyButton Content="Button1"  />
        <blib:MyButton Content="Button2" Background="Purple" />
    </StackPanel>

 

posted @ 2015-04-13 10:14  华子的幸福生活  阅读(871)  评论(2编辑  收藏  举报