C#编程之WPF控件开发(十三)
今天我们开始着手上一篇文章提到的实现用户动态按钮功能。
同样我们对上一章的代码进行修改按键特效。首先我们将原来的按键样式代码删掉,修改如下代码:
1 <Window.Resources> 2 <Style TargetType="Button"> 3 <Setter Property="Template"> 4 <Setter.Value> 5 <ControlTemplate TargetType="Button"> 6 <Border x:Name="Border" CornerRadius="20" BorderBrush="PaleGreen" BorderThickness=" 1"> 7 <Border.Background> 8 <LinearGradientBrush StartPoint=" 0,0.5" EndPoint=" 1,0.5" Opacity=" 0.5"> 9 <GradientStop Color="Green" Offset=" 0.0"/> 10 <GradientStop Color="White" Offset=" 1.0"/> 11 </LinearGradientBrush> 12 </Border.Background> 13 <ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True"/> 14 </Border> 15 <ControlTemplate.Triggers> 16 <Trigger Property="IsPressed" Value="true"> 17 <Setter TargetName="Border" Property="Background"> 18 <Setter.Value> 19 <LinearGradientBrush StartPoint=" 0,0.5" EndPoint="1,0.5"> 20 <GradientStop Color="Blue" Offset="0.0"/> 21 <GradientStop Color="Red" Offset="0.5"/> 22 </LinearGradientBrush> 23 </Setter.Value> 24 </Setter> 25 </Trigger> 26 </ControlTemplate.Triggers> 27 </ControlTemplate> 28 </Setter.Value> 29 </Setter> 30 </Style> 31 </Window.Resources>
删掉后,为:
<Window.Resources> <Style TargetType="Button"> </Style> </Window.Resources>
在添加按键动态效果之前,我们先添加一个动态背景图案样式,及其渐变笔刷和一个按键背景渐变笔刷样本
<Window.Resources> <!--define glass gradient stop resource--> <GradientStopCollection x:Key="myGradientStopResource"> <GradientStop Color="WhiteSmoke" Offset="0.2"/> <GradientStop Color="Transparent" Offset="0.4"/> <GradientStop Color="WhiteSmoke" Offset="0.5"/> <GradientStop Color="Transparent" Offset=" 0.75"/> <GradientStop Color="WhiteSmoke" Offset="0.9"/> <GradientStop Color="Transparent" Offset=" 1.0"/> </GradientStopCollection> <!--define gradient brush resource--> <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75" GradientStops="{StaticResource myGradientStopResource }"/> <!--background brush resource--> <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1"> <GradientStop Color="Gray" Offset="0"/> <GradientStop Color="Cyan" Offset="0.5"/> <GradientStop Color="Gold" Offset="1.0"/> </LinearGradientBrush> <!--define button options--> <Style TargetType="Button"> </Style> </Window.Resources>
为按键类统一添加背景效果:
<!--define button background--> <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/>
通过模板属性设计按键效果:
<!--define button template--> <Setter Property="Template"> <Setter.Value> <!--target type is button--> <ControlTemplate TargetType="{x:Type Button}"> </ControlTemplate> </Setter.Value> </Setter>
添加外观框架:
<Grid Margin="-26,0,-56,2"> <!--outline rectangle--> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="5" Fill="Transparent"/> <!--inner rectangle--> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="20" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20"/> <!--glass rectangle--> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource myGlassBrushResource}" RenderTransformOrigin="0.5,0.5"> <!--rectangle stroke--> <Rectangle.Stroke> <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Color="LightBlue" Offset="0.0"/> <GradientStop Color="Gray" Offset="1.0"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <!--glass rectangle render transform--> <Rectangle.RenderTransform> <TransformGroup> <!--To stretch or contact horizontally or vertially--> <ScaleTransform/> <!--rotate transform by angles--> <RotateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <!--dock panel--> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresent" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black"/> </DockPanel> </Grid>
添加鼠标对按键影响动态效果
<!--control template--> <ControlTemplate.Triggers> <!--mouse over trigger--> <Trigger Property="IsMouseOver" Value="True"> <!--rectangle stroke--> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> </Trigger> <!--Mouse focused trigger--> <Trigger Property="IsFocused" Value="True"> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> </Trigger> <!--Event trigger mouse enter--> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <!--actions--> <EventTrigger.Actions> <!--begin story board--> <BeginStoryboard Name="mouseEnterBeginStoryboard"> <Storyboard> <!--animation--> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" By="-0.2" Duration="0:0:0.5" /> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" By="-0.2" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <!--event trigger mouse leave--> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> </EventTrigger.Actions> </EventTrigger> <!--event trigger button click--> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty="(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" By="360" Duration="0:0:0.5"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </ControlTemplate.Triggers>
我们解析一下部分代码:
<!--mouse over trigger--> <Trigger Property="IsMouseOver" Value="True"> <!--rectangle stroke--> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> </Trigger>
这里操作的是鼠标移到到按键上时,外框显示高亮效果,玻璃框透明度为1(1代表不透明,值越小越透明)。同样,聚焦的时候也是对对应的外框显示相应的效果。当然我们也可以将其改为内框
<Setter Property="Rectangle.Stroke" TargetName="innerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
按同样的方法,我们对鼠标移入到按键框内,为玻璃外框添加收缩效果
<!--Event trigger mouse enter--> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <!--actions--> <EventTrigger.Actions> <!--begin story board--> <BeginStoryboard Name="mouseEnterBeginStoryboard"> <Storyboard> <!--animation--> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" By="-0.2" Duration="0:0:0.5" /> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" By="-0.2" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger>
其中 By="-0.2" 代表收缩程度,值越小,收缩约小。
当鼠标离开按键时,我们将按键效果设置为进入之前的状态:
<!--event trigger mouse leave--> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> </EventTrigger.Actions> </EventTrigger>
最后我们添加当鼠标按下时,玻璃外框按中心点旋转360°:
<!--event trigger button click--> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty="(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" By="360" Duration="0:0:0.5"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger>
通过Margin属性对按键重新布局一下:
<Button Grid.Row="2" Grid.Column="0" Margin="90,2,125,2" Name="submit" Click="Click_submiit" Width="Auto" >View Message</Button> <Button Grid.Row="2" Grid.Column="1" Margin="100,2,120,2" Name="Clear" Click="Click_clean" Width="Auto">Clean Name</Button>
完整代码:
<Window x:Class="WpfControls.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" > <Window.Resources> <!--define glass gradient stop resource--> <GradientStopCollection x:Key="myGradientStopResource"> <GradientStop Color="WhiteSmoke" Offset="0.2"/> <GradientStop Color="Transparent" Offset="0.4"/> <GradientStop Color="WhiteSmoke" Offset="0.5"/> <GradientStop Color="Transparent" Offset=" 0.75"/> <GradientStop Color="WhiteSmoke" Offset="0.9"/> <GradientStop Color="Transparent" Offset=" 1.0"/> </GradientStopCollection> <!--define gradient brush resource--> <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75" GradientStops="{StaticResource myGradientStopResource }"/> <!--background brush resource--> <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1"> <GradientStop Color="Gray" Offset="0"/> <GradientStop Color="Cyan" Offset="0.5"/> <GradientStop Color="Gold" Offset="1.0"/> </LinearGradientBrush> <!--define button options--> <Style TargetType="Button"> <!--define button background--> <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/> <!--define button template--> <Setter Property="Template"> <Setter.Value> <!--target type is button--> <ControlTemplate TargetType="{x:Type Button}"> <Grid Margin="-26,0,-56,2"> <!--outline rectangle--> <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" RadiusX="20" RadiusY="20" StrokeThickness="10" Fill="Transparent"/> <!--inner rectangle--> <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Transparent" StrokeThickness="10" Fill="{TemplateBinding Background}" RadiusX="20" RadiusY="20"/> <!--glass rectangle--> <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" StrokeThickness="2" RadiusX="10" RadiusY="10" Opacity="0" Fill="{StaticResource myGlassBrushResource}" RenderTransformOrigin="0.5,0.5"> <!--rectangle stroke--> <Rectangle.Stroke> <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1"> <LinearGradientBrush.GradientStops> <GradientStop Color="LightBlue" Offset="0.0"/> <GradientStop Color="Gray" Offset="1.0"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Stroke> <!--glass rectangle render transform--> <Rectangle.RenderTransform> <TransformGroup> <!--To stretch or contact horizontally or vertially--> <ScaleTransform/> <!--rotate transform by angles--> <RotateTransform/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <!--dock panel--> <DockPanel Name="myContentPresenterDockPanel"> <ContentPresenter x:Name="myContentPresent" Margin="20" Content="{TemplateBinding Content}" TextBlock.Foreground="Black"/> </DockPanel> </Grid> <!--control template--> <ControlTemplate.Triggers> <!--mouse over trigger--> <Trigger Property="IsMouseOver" Value="True"> <!--rectangle stroke--> <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> </Trigger> <!--Mouse focused trigger--> <Trigger Property="IsFocused" Value="True"> <Setter Property="Rectangle.Stroke" TargetName="innerRectangle" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> </Trigger> <!--Event trigger mouse enter--> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <!--actions--> <EventTrigger.Actions> <!--begin story board--> <BeginStoryboard Name="mouseEnterBeginStoryboard"> <Storyboard> <!--animation--> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" By="-0.2" Duration="0:0:0.5" /> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" By="-0.2" Duration="0:0:0.5" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <!--event trigger mouse leave--> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> </EventTrigger.Actions> </EventTrigger> <!--event trigger button click--> <EventTrigger RoutedEvent="Button.Click"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="glassCube" Storyboard.TargetProperty= "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" By="360" Duration="0:0:0.5"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Grid.Background> <LinearGradientBrush StartPoint="0,1.5" EndPoint="0.5,0.1" Opacity="0.2"> <LinearGradientBrush.GradientStops> <GradientStop Color="Green" Offset="0.0"/> <GradientStop Color="LightBlue" Offset="0.75"/> <GradientStop Color="LightCoral" Offset="1.2"/> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Grid.Background> <Grid.RowDefinitions> <RowDefinition Height="30"/> <RowDefinition Height="30"/> <RowDefinition Height="60"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Label Grid.Column="0" FontSize="14" FontWeight="Bold">Entry your First Name:</Label> <TextBox Grid.Row="0" Grid.Column="1" Name="firstName" Margin="0,5,10,5"/> <Label Grid.Row="1">Entry your Last Name:</Label> <TextBox Grid.Column="1" Grid.Row="1" Name="lastName" Margin="0,5,10,5"/> <Button Grid.Row="2" Grid.Column="0" Margin="90,2,125,2" Name="submit" Click="Click_submiit" Width="Auto" >View Message</Button> <Button Grid.Row="2" Grid.Column="1" Margin="100,2,120,2" Name="Clear" Click="Click_clean" Width="Auto">Clean Name</Button> </Grid> </Window>
编译运行,就可以看到我们想要的效果。
End.
谢谢。