重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
使用WPF怎么编写一个转圈进度条效果?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
创新互联长期为千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为博州企业提供专业的网站建设、成都网站建设,博州网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。1、控件界面
2、控件后台逻辑:
控件后台:
////// 进度条 /// public partial class ProgressBarControl : UserControl { //集成到按指定时间间隔和指定优先级处理的 System.Windows.Threading.Dispatcher 队列中的计时器。 private DispatcherTimer animationTimer; private ProgressBarDataModel _dataModel; private int index = 0; #region 构造方法与加载 ////// 构造方法 /// public ProgressBarControl() { InitializeComponent(); } ////// 加载后刷新 /// /// /// private void ProgressBarControl_OnLoaded(object sender, RoutedEventArgs e) { animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher); //指定时间间隔 animationTimer.Interval = new TimeSpan(0, 0, 0, 0, TimeSpan); if (EllipseCount < 1) { EllipseCount = 12; } for (int i = 0; i < EllipseCount; i++) { ProgressBarCanvas.Children.Add(new Ellipse()); } var dataModel = new ProgressBarDataModel() { CanvasSize = CanvasSize, EclipseSize = EllipseSize }; _dataModel = dataModel; this.DataContext = dataModel; } #endregion #region 属性 ////// 获取或设置圆圈数量 /// 默认12 /// public double EllipseCount { get { return (double)GetValue(EllipseCountProperty); } set { SetValue(EllipseCountProperty, value); } } public static readonly DependencyProperty EllipseCountProperty = DependencyProperty.Register("EllipseCount", typeof(double), typeof(ProgressBarControl), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); ////// 获取或设置圆圈大小 /// 默认10 /// public double EllipseSize { get { return (double)GetValue(EllipseSizeProperty); } set { SetValue(EllipseSizeProperty, value); } } public static readonly DependencyProperty EllipseSizeProperty = DependencyProperty.Register("EllipseSize", typeof(double), typeof(ProgressBarControl), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); ////// 获取或设置面板大小 /// 默认80 /// public double CanvasSize { get { return (double)GetValue(CanvasSizeProperty); } set { SetValue(CanvasSizeProperty, value); } } public static readonly DependencyProperty CanvasSizeProperty = DependencyProperty.Register("CanvasSize", typeof(double), typeof(ProgressBarControl), new FrameworkPropertyMetadata(80.0, FrameworkPropertyMetadataOptions.AffectsRender)); ////// 获取或设置每次旋转角度 /// 默认10.0 /// public double StepAngle { get { return (double)GetValue(StepAngleProperty); } set { SetValue(StepAngleProperty, value); } } public static readonly DependencyProperty StepAngleProperty = DependencyProperty.Register("StepAngle", typeof(double), typeof(ProgressBarControl), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); ////// 获取或设置每次旋转间隔时间(毫秒) /// 默认100毫秒 /// public int TimeSpan { get { return (int)GetValue(TimeSpanProperty); } set { SetValue(TimeSpanProperty, value); } } public static readonly DependencyProperty TimeSpanProperty = DependencyProperty.Register("TimeSpan", typeof(int), typeof(ProgressBarControl), new FrameworkPropertyMetadata(100, FrameworkPropertyMetadataOptions.AffectsRender)); #endregion #region 方法 ////// Canvas加载 /// /// /// private void HandleLoaded(object sender, RoutedEventArgs e) { //设置设置圆的位置和旋转角度 SetEclipsePosition(_dataModel); //DesignerProperties 提供用于与设计器进行通信的附加属性。 if (!DesignerProperties.GetIsInDesignMode(this)) { if (this.Visibility == System.Windows.Visibility.Visible) { //超过计时器间隔时发生。 animationTimer.Tick += HandleAnimationTick; animationTimer.Start(); } } } ////// 设置圆的位置和旋转角度 /// private void SetEclipsePosition(ProgressBarDataModel dataModel) { //圆周长就是:C = π * d 或者C=2*π*r(其中d是圆的直径,r是圆的半径) double r =dataModel.R; var children=ProgressBarCanvas.Children; int count = children.Count; double step = (Math.PI * 2) / count; //根据圆中正弦、余弦计算距离 int index = 0; foreach (var element in children) { var ellipse = element as Ellipse; //透明度 var opacity = Convert.ToDouble(index)/(count - 1); ellipse.SetValue(UIElement.OpacityProperty, opacity<0.05?0.05:opacity); //距离 double left = r + Math.Sin(step*index)*r; ellipse.SetValue(Canvas.LeftProperty,left); double top = r - Math.Cos(step*index)*r; ellipse.SetValue(Canvas.TopProperty, top); index++; } } ////// Canvas卸载时 /// /// /// private void HandleUnloaded(object sender, RoutedEventArgs e) { animationTimer.Stop(); //除去委托 animationTimer.Tick -= HandleAnimationTick; } ////// 超过计时器间隔时发生。 /// /// /// private void HandleAnimationTick(object sender, EventArgs e) { //设置旋转角度 SpinnerRotate.Angle = (SpinnerRotate.Angle + StepAngle) % 360; } #endregion }
数据Model类:
////// 进度条Model类 /// public class ProgressBarDataModel { public double EclipseSize { get; set; } public double CanvasSize { get; set; } public double ViewBoxSize { get { double length = Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize); return length; } } public double EclipseLeftLength { get { double length = Convert.ToDouble(CanvasSize) / 2; return length; } } public double R { get { double length = (Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize)) / 2; return length; } } }
3、取用控件
看完上述内容,你们掌握使用WPF怎么编写一个转圈进度条效果的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!