老板加薪!看我做的WPF Loading!!!


老板加薪!看我做的WPF Loading!!!

控件名:RingLoading

作者:WPFDevelopersOrg

原文链接: https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 框架使用大于等于.NET40

  • Visual Studio 2022;

  • 项目使用 MIT 开源许可协议;

  • 老板觉得公司系统等待动画转圈太简单,所以需要做一个稍微好看点的,就有这篇等待RingLoading动画;

视频效果预览??https://www.zhihu.com/zvideo/1540649421552779264

  • 最外层使用Viewbox为父控件内部嵌套创建三组 Grid -> Ellipse 、 Border
    分别给它们指定不同的Angle从左侧开始 -135 225 54,做永久 Angle 动画;
  • PART_Ring1.RotateTransform.AngleFrom -135-495
  • PART_Ring2.RotateTransform.AngleFrom 225-585
  • PART_Ring3.RotateTransform.AngleFrom -54-315
  • 如何绘制;

  • EllipseStrokeDashArray进行设置23 100就能达到效果;

  • Border 做为圆设置 Effect 可实现阴影效果;

1)RingLoading.cs代码如下;

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 <= 0)
                return;

            var progress = control.ProgressValue / maxValue;
            control.SetCurrentValue(ProgressProperty, progress.ToString("P0"));
        }
    }
}

2)RingLoading.xaml代码如下;

 

3)RingLoadingExample.xaml代码如下;


    
        
    

RingLoading|Github
RingLoading|码云
RingLoading.xaml|Github
RingLoading.xaml|码云