开发工具与关键技术:自定义TextBox和Button控件
作者:邓崇富
撰写时间:2019 年 8 月 7 日
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
自定义控件有两种写法,一种是快速定义法,另一种是手动写法。快速定义法就是在页面的设计器里选中你要自定义的控件,然后鼠标右键,然后选择编辑模板,再选择编辑副本,再然后选择模板存放的位置。
详细步骤如下图:
点击确认后就可以看到控件的默认样式,并且可以在里面修改该控件的样式。
下面说的手动在资源字典里自定义TextBox和Button控件的样式的详细代码:
<Style x:Key="textBox" TargetType="TextBox">
<!--字体颜色-->
<Setter Property="Foreground" Value="Black"/>
<!--字体大小-->
<Setter Property="FontSize" Value="16"/>
<!--控件模板-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border BorderBrush="LightGray" BorderThickness="1" CornerRadius="3">
<ScrollViewer x:Name="PART_ContentHost"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--按钮样式-->
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<!--定义动画资源-->
<ControlTemplate.Resources>
<Storyboard x:Key="Timeline1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
<!--1秒等于1000毫秒,1毫秒等于1000微秒,1微妙等于1000纳秒-->
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Timeline2">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<!--定义动画资源_end-->
<!--定义视觉树-->
<Border BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius="3,3,3,3">
<!--小按钮的样式-->
<Border x:Name="border" Background="SkyBlue" BorderBrush="White" BorderThickness="1" CornerRadius="3,3,3,3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.507*"/>
<RowDefinition Height="0.493*"/>
</Grid.RowDefinitions>
<!--边框-->
<Border Opacity="0" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="0,0,0,0">
<Border.Background>
<!--RadialgradientBrush(圆形梯度画刷)
设定圆心坐标和X坐标和Y坐标的值就可以画一个圆形渐变-->
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<!--ScaleTransform(缩放变化):
包括属性ScaleX、ScaleY、CenterX、CenterY,其中ScaleX、ScaleY属性表示对象在X、Y轴进行缩放的倍数,使用CenterX 和 CenterY属性指定一个中心点。-->
<ScaleTransform ScaleX="1.702" ScaleY="2.243"/>
<!--SkewTransform(扭曲变化):
包括属性AngleX、AngleY、CenterX、CenterY。其中使用AngleX让元素相对X轴倾斜角度,AngleY是让元素围绕Y轴的倾斜角度。同样CenterX和CenterY是中心点位置。-->
<SkewTransform AngleX="0" AngleY="0"/>
<!--RotateTransform(旋转变化):
包括属性Angle(旋转角度),CenterX、CenterY(旋转的中心)-->
<RotateTransform Angle="0"/>
<!--TranslateTransform(平移变化):
包含X、Y 两种属性,以原来的对象为坐标原点(0,0),然后向X轴、Y轴进行平移变换。-->
<TranslateTransform X="-0.368" Y="-0.152"/>
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#B28DBDFF" Offset="0"/>
<GradientStop Color="#008DBDFF" Offset="1"/>
</RadialGradientBrush>
</Border.Background>
</Border>
<!-- 模板绑定(TemplateBinding)
使用TemplateBinding扩展把TextBlock的Content设置为控件的Content。-->
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2" Text="{TemplateBinding Content}" TextBlock.Foreground="White"/>
<Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="0,0,3,3">
<Border.Background>
<!-- LinearGradientBrush(线性梯度画刷)-->
<LinearGradientBrush StartPoint="0.494,0.028" EndPoint="0.494,0.889" >
<GradientStop Color="#99FFFFFF" Offset="0"/>
<GradientStop Color="#33FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</Border>
<!--定义视觉树_end-->
<!--定义触发器-->
<!--WPF trigger的主要类型有:Trigger、MultiTrigger、DataTrigger、MultiDataTrigger、EventTrigger几种。trigger主要运用的场景在Style、ControlTemplate、DataTemplate三个地方-->
<ControlTemplate.Triggers>
<!--UIElement.IsMouseOver 属性:菜单项的“按下”状态-->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Opacity" TargetName="shine" Value="0.4"/>
<Setter Property="Background" TargetName="border" Value="#FFA4C0F0"/>
<Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
</Trigger>
<!-- MenuItem.IsPressed 属性:按钮的“鼠标悬停”状态-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<!--WPF样式动画Trigger.EnterActions-->
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
</Trigger.EnterActions>
<!--WPF样式动画Trigger.ExitActions(ExitActions其实可以不做任何事情)-->
<Trigger.ExitActions>
<BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<!--定义触发器_End-->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>