老板加薪!看我做的WPF Loading!!!
控件名:RingLoading
作者:WPFDevelopersOrg
原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal
- 框架使用大于等于.NET40;
- Visual Studio 2022;
- 项目使用 MIT 开源许可协议;
- 老板觉得公司系统等待动画转圈太简单,所以需要做一个稍微好看点的,就有这篇等待RingLoading动画
- 最外层使用Viewbox为父控件内部嵌套创建三组 Grid -> Ellipse 、 Border
分别给它们指定不同的Angle从左侧开始 -135 225 54,做永久 Angle 动画;
- PART_Ring1.RotateTransform.Angle从From -135 到 -495;
- PART_Ring2.RotateTransform.Angle从From 225 到 -585;
- PART_Ring3.RotateTransform.Angle从From -54 到 -315;
- 如何绘制;

- 对Ellipse的StrokeDashArray进行设置23 100就能达到效果;
- Border 做为圆设置 Effect 可实现阴影效果;
1)RingLoading.cs代码如下;
[code]using System.Windows;using System.Windows.Controls;namespace WPFDevelopers.Controls{ public class RingLoading : Control { // Using a DependencyProperty as the backing store for IsStart. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsStartProperty = DependencyProperty.Register("IsStart", typeof(bool), typeof(RingLoading), new PropertyMetadata(default)); // Using a DependencyProperty as the backing store for ProgressValue. This enables animation, styling, binding, etc... public static readonly DependencyProperty ProgressValueProperty = DependencyProperty.Register("ProgressValue", typeof(double), typeof(RingLoading), new PropertyMetadata(0d, OnProgressValueChangedCallBack)); // Using a DependencyProperty as the backing store for Progress. This enables animation, styling, binding, etc... internal static readonly DependencyProperty ProgressProperty = DependencyProperty.Register("Progress", typeof(string), typeof(RingLoading), new PropertyMetadata(default)); // Using a DependencyProperty as the backing store for Maximum. This enables animation, styling, binding, etc... public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(RingLoading), new PropertyMetadata(100d, OnMaximumPropertyChangedCallBack)); // Using a DependencyProperty as the backing store for Description. This enables animation, styling, binding, etc... public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(RingLoading), new PropertyMetadata(default)); static RingLoading() { DefaultStyleKeyProperty.OverrideMetadata(typeof(RingLoading), new FrameworkPropertyMetadata(typeof(RingLoading))); } public bool IsStart { get => (bool)GetValue(IsStartProperty); set => SetValue(IsStartProperty, value); } public double ProgressValue { get => (double)GetValue(ProgressValueProperty); set => SetValue(ProgressValueProperty, value); } internal string Progress { get => (string)GetValue(ProgressProperty); set => SetValue(ProgressProperty, value); } public double Maximum { get => (double)GetValue(MaximumProperty); set => SetValue(MaximumProperty, value); } public string Description { get => (string)GetValue(DescriptionProperty); set => SetValue(DescriptionProperty, value); } private static void OnProgressValueChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is RingLoading control)) return; if (!double.TryParse(e.NewValue?.ToString(), out var value)) return; var progress = value / control.Maximum; control.SetCurrentValue(ProgressProperty, progress.ToString("P0")); } private static void OnMaximumPropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (!(d is RingLoading control)) return; if (!double.TryParse(e.NewValue?.ToString(), out var maxValue)) return; if (maxValue |