这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到WPF中动画效果不错,于是自己研究了一下,还真让我做出来了,废话不多说了,先上效果。

WPF利用动画实现圆形进度条

  这个效果是不是还不错?这里面实现了数字实时显示以及根据进度进行自动渐变的效果。实现原理其实很简单,利用WPF动画,其中主要元素有border(实现里外层圆的效果),Arc扇面(就是用来实现外层填充效果的),Label(用来显示进度百分比)。

1.实现里外双层圆背景效果

  这里我用了两个border实现,将两个border的CornerRadius设置为500,这样保证他们是两个圆(这里不用Ellipse是我觉得border可能更加省资源),然后将他们他们的宽度设置为100和80,让他们作为同心圆。其他设置主要为了美观此处不再多说,一会上代码即可。

2.利用Arc实现填充效果

  说起这个Arc还真是个好东西,之前只是知道它是个扇面,但是没想到还可以实现弧度填充,这得益于它的ArcThickness可以设置为小数,这个具体数值可以在blend中自己调节一下,ArcThicknessUnit设置为Percent,意思是单位是百分比。然后利用Arc的StartAngle和EndAngle就可以轻松实现进度填充了。

3.利用Label实现进度显示

  最后在中间放置一个Label,然后将它的Text属性绑定到Arc的EndAngle上,之后自己写个Convert将角度转化为百分比即可。

4.动画的实现

  剩下的就可以利用blend做个动画,动画效果十分简单,开始时间,结束时间,开始角度,结束角度。这样简单的填充效果就实现了,最后还要实现渐变效果,好吧,其实也比较简单,同样的开始时间,结束时间,开始颜色,结束颜色,然后两个动画的时间间隔相同就好,这样效果比较同步。

注意:最后说一句,用ViewBox将整个效果框起来,这样以后无论你怎么拖拽这个空间,内部都不会出现变形的效果了。

代码如下:

 1 <UserControl x:Class="MyUserControlLibrary.WaitingAndProgress"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
 7              xmlns:local ="clr-namespace:MyUserControlLibrary"
 8              mc:Ignorable="d" 
 9              d:DesignHeight="100" d:DesignWidth="100" Loaded="UserControl_Loaded">
10     <UserControl.Resources>
11         <local:ConverterCircleToPercent x:Key="converter"/>
12         <Storyboard x:Key="MainStoryboard" RepeatBehavior="Forever">
13             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ShowArea">
14                 <EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="360"/>
15             </DoubleAnimationUsingKeyFrames>
16             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="minCircle">
17                 <EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="360"/>
18             </DoubleAnimationUsingKeyFrames>
19         </Storyboard>
20         <Storyboard x:Key="FillStoryboard" Completed="Storyboard_Completed">
21             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(ed:Arc.EndAngle)" Storyboard.TargetName="FillArea">
22                 <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
23                 <EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0"/>
24             </DoubleAnimationUsingKeyFrames>
25             <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="FillArea">
26                 <EasingColorKeyFrame KeyTime="0:0:0" Value="#FFFF0000"/>
27                 <EasingColorKeyFrame KeyTime="0:0:0.05" Value="#FF008000"/>
28             </ColorAnimationUsingKeyFrames>
29         </Storyboard>
30     </UserControl.Resources>
31     <Viewbox>
32     <Grid>
33             <Border Name="MaxCircle" CornerRadius="500" Width="100" Height="100" Background="White"  Opacity="0.2"/>
34             <Border Name="minCircle" CornerRadius="500" Width="80" Height="80" BorderBrush="black" BorderThickness="2" Opacity="0.4" RenderTransformOrigin="0.5,0.5">
35                 <Border.RenderTransform>
36                     <TransformGroup>
37                         <ScaleTransform/>
38                         <SkewTransform/>
39                         <RotateTransform/>
40                         <TranslateTransform/>
41                     </TransformGroup>
42                 </Border.RenderTransform>
43                 <Border.Background>
44                     <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
45                         <GradientStop Color="White" Offset="0"/>
46                         <GradientStop Color="Transparent" Offset="0.5"/>
47                         <GradientStop Color="White" Offset="1"/>
48                     </LinearGradientBrush>
49                 </Border.Background>
50             </Border>
51             <ed:Arc Name="FillArea" ArcThickness="0.18" ArcThicknessUnit="Percent" StartAngle="0" EndAngle="0" Width="95" Height="95" Stretch="None" Opacity="0.8" Fill="Red"/>
52             <Label Name="ShowLabel" Width="60" Height="60" FontFamily="宋体" FontWeight="Bold" Content="{Binding ElementName=FillArea,Path=EndAngle,Converter={StaticResource converter}}" FontSize="32" Foreground="White" Opacity="0.8" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
53     </Grid>
54     </Viewbox>
55 </UserControl>
前端XMAL

相关文章: