• 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>
  • 相关阅读:
    Effective C# 原则37:使用标准的配置机制(译)
    Effective C# 原则31:选择小而简单的函数(译)
    Effective C# 原则24:选择申明式编程而不是命令式编程(译)
    Effective C# 原则34:创建大容量的Web API(译)
    Effective C# 原则27:避免使用ICloneable(译)
    Effective C# 第4章:创建基于二进制的组件(译)
    Effective C# 原则39:使用.Net验证(译)
    Effective C# 原则35:选择重写函数而不是使用事件句柄(译)
    Effective C# 原则25: 让你的类型支持序列化(译)
    Effective C# 原则38:使用和支持数据绑定(译)
  • 原文地址:https://www.cnblogs.com/huaci/p/4421480.html
Copyright © 2020-2023  润新知