WPF實現轉圈進度條效果

在設計界面時,有時會遇到進度條,本次講解WPF如何設計自定義的繞圈進度條,直接上代碼:

1、控件界面
01
<UserControl x:Class="ProgressBarControl"
02
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
03
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
04
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
05
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
06
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="300"
07
Background="Gray" Loaded="ProgressBarControl_OnLoaded">
08

09
<Grid>
10
<Grid.Resources>
11
<Style TargetType="Ellipse">
12
<Setter Property="Height" Value="{Binding EclipseSize}"></Setter>
13
<Setter Property="Width" Value="{Binding EclipseSize}"></Setter>
14
<Setter Property="Stretch" Value="Fill"></Setter>
15

16 17 18 19 21 24 28 29 34 35 36 37 38 39 40 41 42 43 2、控件後臺邏輯: 控件後臺: 001 /// 002 /// 進度條 003 /// 004 public partial class ProgressBarControl : UserControl 005 { 006 //集成到按指定時間間隔和指定優先級處理的 System.Windows.Threading.Dispatcher 隊列中的計時器。 007 private DispatcherTimer animationTimer; 008 private ProgressBarDataModel _dataModel; 009 private int index = 0; 010 #region 構造方法與加載 011 /// 012 /// 構造方法 013 /// 014 public ProgressBarControl() 015 { 016 InitializeComponent(); 017 018 } 019 /// 020 /// 加載後刷新 021 /// 022 /// 023 /// 024 private void ProgressBarControl_OnLoaded(object sender, RoutedEventArgs e) 025 { 026 animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher); 027 //指定時間間隔 028 animationTimer.Interval = new TimeSpan(0, 0, 0, 0, TimeSpan); 029 if (EllipseCount < 1) 030 { 031 EllipseCount = 12; 032 } 033 for (int i = 0; i < EllipseCount; i++) 034 { 035 ProgressBarCanvas.Children.Add(new Ellipse()); 036 } 037 var dataModel = new ProgressBarDataModel() 038 { 039 CanvasSize = CanvasSize, 040 EclipseSize = EllipseSize 041 }; 042 _dataModel = dataModel; 043 this.DataContext = dataModel; 044 } 045 #endregion 046 047 #region 屬性 048 /// 049 /// 獲取或設置圓圈數量 050 /// 默認12 051 /// 052 public double EllipseCount 053 { 054 get { return (double)GetValue(EllipseCountProperty); } 055 set { SetValue(EllipseCountProperty, value); } 056 } 057 public static readonly DependencyProperty EllipseCountProperty = 058 DependencyProperty.Register("EllipseCount", typeof(double), typeof(ProgressBarControl), 059 new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); 060 061 /// 062 /// 獲取或設置圓圈大小 063 /// 默認10 064 /// 065 public double EllipseSize 066 { 067 get { return (double)GetValue(EllipseSizeProperty); } 068 set { SetValue(EllipseSizeProperty, value); } 069 } 070 public static readonly DependencyProperty EllipseSizeProperty = 071 DependencyProperty.Register("EllipseSize", typeof(double), typeof(ProgressBarControl), 072 new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); 073 074 /// 075 /// 獲取或設置面板大小 076 /// 默認80 077 /// 078 public double CanvasSize 079 { 080 get { return (double)GetValue(CanvasSizeProperty); } 081 set { SetValue(CanvasSizeProperty, value); } 082 } 083 public static readonly DependencyProperty CanvasSizeProperty = 084 DependencyProperty.Register("CanvasSize", typeof(double), typeof(ProgressBarControl), 085 new FrameworkPropertyMetadata(80.0, FrameworkPropertyMetadataOptions.AffectsRender)); 086 087 /// 088 /// 獲取或設置每次旋轉角度 089 /// 默認10.0 090 /// 091 public double StepAngle 092 { 093 get { return (double)GetValue(StepAngleProperty); } 094 set { SetValue(StepAngleProperty, value); } 095 } 096 097 public static readonly DependencyProperty StepAngleProperty = 098 DependencyProperty.Register("StepAngle", typeof(double), typeof(ProgressBarControl), 099 new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); 100 /// 101 /// 獲取或設置每次旋轉間隔時間(毫秒) 102 /// 默認100毫秒 103 /// 104 public int TimeSpan 105 { 106 get { return (int)GetValue(TimeSpanProperty); } 107 set { SetValue(TimeSpanProperty, value); } 108 } 109 public static readonly DependencyProperty TimeSpanProperty = 110 DependencyProperty.Register("TimeSpan", typeof(int), typeof(ProgressBarControl), 111 new FrameworkPropertyMetadata(100, FrameworkPropertyMetadataOptions.AffectsRender)); 112 113 #endregion 114 115 #region 方法 116 /// 117 /// Canvas加載 118 /// 119 /// 120 /// 121 private void HandleLoaded(object sender, RoutedEventArgs e) 122 { 123 //設置設置圓的位置和旋轉角度 124 SetEclipsePosition(_dataModel); 125 //DesignerProperties 提供用於與設計器進行通信的附加屬性。 126 if (!DesignerProperties.GetIsInDesignMode(this)) 127 { 128 if (this.Visibility == System.Windows.Visibility.Visible) 129 { 130 //超過計時器間隔時發生。 131 animationTimer.Tick += HandleAnimationTick; 132 animationTimer.Start(); 133 } 134 } 135 } 136 137 /// 138 /// 設置圓的位置和旋轉角度 139 /// 140 private void SetEclipsePosition(ProgressBarDataModel dataModel) 141 { 142 //圓周長就是:C = π * d 或者C=2*π*r(其中d是圓的直徑,r是圓的半徑) 143 double r =dataModel.R; 144 145 var children=ProgressBarCanvas.Children; 146 int count = children.Count; 147 double step = (Math.PI * 2) / count; 148 149 //根據圓中正弦、餘弦計算距離 150 int index = 0; 151 foreach (var element in children) 152 { 153 var ellipse = element as Ellipse; 154 //透明度 155 var opacity = Convert.ToDouble(index)/(count - 1); 156 ellipse.SetValue(UIElement.OpacityProperty, opacity<0.05?0.05:opacity); 157 //距離 158 double left = r + Math.Sin(step*index)*r; 159 ellipse.SetValue(Canvas.LeftProperty,left); 160 double top = r - Math.Cos(step*index)*r; 161 ellipse.SetValue(Canvas.TopProperty, top); 162 163 index++; 164 } 165 } 166 167 /// 168 /// Canvas卸載時 169 /// 170 /// 171 /// 172 private void HandleUnloaded(object sender, RoutedEventArgs e) 173 { 174 animationTimer.Stop(); 175 //除去委託 176 animationTimer.Tick -= HandleAnimationTick; 177 } 178 179 /// 180 /// 超過計時器間隔時發生。 181 /// 182 /// 183 /// 184 private void HandleAnimationTick(object sender, EventArgs e) 185 { 186 //設置旋轉角度 187 SpinnerRotate.Angle = (SpinnerRotate.Angle + StepAngle) % 360; 188 } 189 #endregion 190 } 數據Model類: 01 /// 02 /// 進度條Model類 03 /// 04 public class ProgressBarDataModel 05 { 06 public double EclipseSize { get; set; } 07 public double CanvasSize { get; set; } 08 public double ViewBoxSize 09 { 10 get 11 { 12 double length = Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize); 13 return length; 14 } 15 } 16 public double EclipseLeftLength 17 { 18 get 19 { 20 double length = Convert.ToDouble(CanvasSize) / 2; 21 return length; 22 } 23 } 24 public double R 25 { 26 get 27 { 28 double length = (Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize)) / 2; 29 return length; 30 } 31 } 32 } 3、取用控件 1 本文原創自news.mkq.online
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章