這是個人第一篇隨筆,最近由於工做須要,開始學習WPF相關技術,本身想實現如下圓形進度條的效果,逛了園子發現基本都是好久之前的文章,實現方式通常都是GDI實現的,想到WPF中動畫效果不錯,因而本身研究了一下,還真讓我作出來了,廢話很少說了,先上效果。前端
這個效果是否是還不錯?這裏面實現了數字實時顯示以及根據進度進行自動漸變的效果。實現原理其實很簡單,利用WPF動畫,其中主要元素有border(實現裏外層圓的效果),Arc扇面(就是用來實現外層填充效果的),Label(用來顯示進度百分比)。express
1.實現裏外雙層圓背景效果ide
這裏我用了兩個border實現,將兩個border的CornerRadius設置爲500,這樣保證他們是兩個圓(這裏不用Ellipse是我以爲border可能更加省資源),而後將他們他們的寬度設置爲100和80,讓他們做爲同心圓。其餘設置主要爲了美觀此處再也不多說,一會上代碼便可。學習
2.利用Arc實現填充效果動畫
提及這個Arc還真是個好東西,以前只是知道它是個扇面,可是沒想到還能夠實現弧度填充,這得益於它的ArcThickness能夠設置爲小數,這個具體數值能夠在blend中本身調節一下,ArcThicknessUnit設置爲Percent,意思是單位是百分比。而後利用Arc的StartAngle和EndAngle就能夠輕鬆實現進度填充了。this
3.利用Label實現進度顯示spa
最後在中間放置一個Label,而後將它的Text屬性綁定到Arc的EndAngle上,以後本身寫個Convert將角度轉化爲百分比便可。3d
4.動畫的實現code
剩下的就能夠利用blend作個動畫,動畫效果十分簡單,開始時間,結束時間,開始角度,結束角度。這樣簡單的填充效果就實現了,最後還要實現漸變效果,好吧,其實也比較簡單,一樣的開始時間,結束時間,開始顏色,結束顏色,而後兩個動畫的時間間隔相同就好,這樣效果比較同步。orm
注意:最後說一句,用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>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Windows; 6 using System.Windows.Controls; 7 using System.Windows.Data; 8 using System.Windows.Documents; 9 using System.Windows.Input; 10 using System.Windows.Media; 11 using System.Windows.Media.Animation; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace MyUserControlLibrary 17 { 18 /// <summary> 19 /// WaitingAndProgress.xaml 的交互邏輯 20 /// </summary> 21 public partial class WaitingAndProgress : UserControl 22 { 23 #region 屬性 24 25 private WaitAndProgressType showType = WaitAndProgressType.WaitingAndProgress; 26 /// <summary> 27 /// 當前樣式類型 28 /// </summary> 29 [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Appreance"),System.ComponentModel.Description("設置或獲取當前樣式類型")] 30 public WaitAndProgressType ShowType { 31 get { 32 return showType; 33 } 34 set { 35 showType = value; 36 } 37 } 38 39 #endregion 40 41 public WaitingAndProgress() 42 { 43 InitializeComponent(); 44 } 45 46 #region 方法 47 48 public void setPrecent(double d) { 49 if (showType == WaitAndProgressType.Waiting) { 50 return; 51 } 52 Storyboard b = (Storyboard)this.Resources["FillStoryboard"]; 53 DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[0]; 54 ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[1]; 55 if (d >= 0 && d <= 10) 56 { 57 cf.KeyFrames[1].Value = ToColor("#FFFF3300"); 58 } 59 if (d > 10 && d <= 20) 60 { 61 cf.KeyFrames[1].Value = ToColor("#FFFF6600"); 62 } 63 if (d > 20 && d <= 30) 64 { 65 cf.KeyFrames[1].Value = ToColor("#FFFF9900"); 66 } 67 if (d > 30 && d <= 40) 68 { 69 cf.KeyFrames[1].Value = ToColor("#FFFFCC00"); 70 } 71 if (d > 40 && d <= 50) 72 { 73 cf.KeyFrames[1].Value = ToColor("#FFFFFF00"); 74 } 75 if (d > 50 && d <= 60) 76 { 77 cf.KeyFrames[1].Value = ToColor("#FFCCFF00"); 78 } 79 if (d > 60 && d <= 70) 80 { 81 cf.KeyFrames[1].Value = ToColor("#FF99FF00"); 82 } 83 if (d > 70 && d <= 80) 84 { 85 cf.KeyFrames[1].Value = ToColor("#FF66FF00"); 86 } 87 if (d > 80 && d <= 90) 88 { 89 cf.KeyFrames[1].Value = ToColor("#FF33FF00"); 90 } 91 if (d > 90 && d <= 100) 92 { 93 cf.KeyFrames[1].Value = ToColor("#FF00FF00"); 94 } 95 df.KeyFrames[1].Value = d*3.6; 96 b.Begin(); 97 } 98 99 /// <summary> 100 /// 將blend的8位顏色值轉爲color 101 /// </summary> 102 /// <param name="colorName"></param> 103 /// <returns></returns> 104 public Color ToColor(string colorName) 105 { 106 if (colorName.StartsWith("#")) 107 colorName = colorName.Replace("#", string.Empty); 108 int v = int.Parse(colorName, System.Globalization.NumberStyles.HexNumber); 109 return new Color() 110 { 111 A = Convert.ToByte((v >> 24) & 255), 112 R = Convert.ToByte((v >> 16) & 255), 113 G = Convert.ToByte((v >> 8) & 255), 114 B = Convert.ToByte((v >> 0) & 255) 115 }; 116 } 117 118 #endregion 119 120 #region 事件 121 122 //載入時事件處理 123 private void UserControl_Loaded(object sender, RoutedEventArgs e) 124 { 125 if (showType != WaitAndProgressType.Progress) 126 { 127 Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"]; 128 b1.Begin(); 129 if (showType == WaitAndProgressType.Waiting) 130 { 131 ShowLabel.Visibility = System.Windows.Visibility.Hidden; 132 } 133 else { 134 ShowLabel.Visibility = System.Windows.Visibility.Visible; 135 } 136 } 137 else { 138 Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"]; 139 b1.Stop(); 140 ShowLabel.Visibility = System.Windows.Visibility.Visible; 141 } 142 } 143 144 //漸變更畫完成時 145 private void Storyboard_Completed(object sender, EventArgs e) 146 { 147 Storyboard b = (Storyboard)this.Resources["FillStoryboard"]; 148 ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[1]; 149 DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[0]; 150 df.KeyFrames[0].Value = df.KeyFrames[1].Value; 151 cf.KeyFrames[0].Value = cf.KeyFrames[1].Value; 152 } 153 154 #endregion 155 156 157 } 158 }
1 using System; 2 using System.Collections.Generic; 3 using System.Globalization; 4 using System.Linq; 5 using System.Text; 6 using System.Windows.Data; 7 8 namespace MyUserControlLibrary 9 { 10 /// <summary> 11 /// 將角度轉化成百分比 12 /// </summary> 13 public class ConverterCircleToPercent:IValueConverter 14 { 15 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 16 { 17 return (int)(double.Parse(value.ToString()) * 10 / 36); 18 } 19 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 20 { 21 throw new NullReferenceException(); 22 } 23 } 24 }