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

虚幻大学 xuhss 184℃ 0评论

? 优质资源分享 ?

学习路线指引(点击解锁) 知识定位 人群定位
? Python实战微信订餐小程序 ? 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
?Python量化交易实战? 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

老板加薪!看我做的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.AngleFrom -135-495
  • PART_Ring2.RotateTransform.AngleFrom 225-585
  • PART_Ring3.RotateTransform.AngleFrom -54-315
  • 如何绘制;

954b5075 811e 4f8c 9548 4a884393710c - 老板加薪!看我做的WPF Loading!!!

  • 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代码如下;

 <Style TargetType="controls:RingLoading" BasedOn="{StaticResource ControlBasicStyle}">
 <Setter Property="Template">
 <Setter.Value>
 <ControlTemplate TargetType="controls:RingLoading">
 <ControlTemplate.Resources>
 <Storyboard x:Key="PART\_Resource\_Storyboard" RepeatBehavior="Forever">
 <DoubleAnimation To="-495" Duration="0:0:1.5" Storyboard.TargetName="PART\_Ring1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"/>
 <DoubleAnimation To="585" Duration="0:0:1.5" Storyboard.TargetName="PART\_Ring2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"/>
 <DoubleAnimation To="-315" Duration="0:0:1.5" Storyboard.TargetName="PART\_Ring3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"/>
 Storyboard>
                    ControlTemplate.Resources>

                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="Auto"/>
                        Grid.RowDefinitions>

                        <Viewbox HorizontalAlignment="Center" VerticalAlignment="Center" >
                            <Border Padding="10" Width="100" Height="100" >
                                <Grid>
                                    <Grid x:Name="PART\_Ring1" Width="60" Height="60" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
                                        <Grid.RenderTransform>
                                            <TransformGroup>
                                                <ScaleTransform/>
                                                <SkewTransform/>
                                                <RotateTransform Angle="-135"/>
                                                <TranslateTransform/>
                                            TransformGroup>
                                        Grid.RenderTransform>
                                        <Ellipse Stroke="Red" StrokeThickness="2" StrokeDashArray="23 100" RenderTransformOrigin="0.5,0.5"/>
                                        <Border Width="10" Height="10" CornerRadius="10" Background="Red" HorizontalAlignment="Right" Margin="0,0,-4,0">
                                            <Border.Effect>
                                                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="Red"/>
                                            Border.Effect>
                                        Border>
                                    Grid>

                                    <Grid x:Name="PART\_Ring2" Width="60" Height="60" HorizontalAlignment="Left" VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5">
                                        <Grid.RenderTransform>
                                            <TransformGroup>
                                                <ScaleTransform/>
                                                <SkewTransform/>
                                                <RotateTransform Angle="225"/>
                                                <TranslateTransform/>
                                            TransformGroup>
                                        Grid.RenderTransform>
                                        <Ellipse Stroke="Purple" StrokeThickness="2" StrokeDashArray="23 100"/>
                                        <Border Width="10" Height="10" CornerRadius="10" Background="Purple" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,-4">
                                            <Border.Effect>
                                                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="Purple"/>
                                            Border.Effect>
                                        Border>
                                    Grid>

                                    <Grid x:Name="PART\_Ring3" Width="60" Height="60" HorizontalAlignment="Right" VerticalAlignment="Bottom" RenderTransformOrigin="0.5,0.5">
                                        <Grid.RenderTransform>
                                            <TransformGroup>
                                                <ScaleTransform/>
                                                <SkewTransform/>
                                                <RotateTransform Angle="45"/>
                                                <TranslateTransform/>
                                            TransformGroup>
                                        Grid.RenderTransform>
                                        <Ellipse Stroke="#0fb8b2" StrokeThickness="2" StrokeDashArray="23 100"/>
                                        <Border Width="10" Height="10" CornerRadius="10" Background="#0fb8b2" HorizontalAlignment="Right" Margin="0,0,-4,0">
                                            <Border.Effect>
                                                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="#0fb8b2"/>
                                            Border.Effect>
                                        Border>
                                    Grid>
                                Grid>
                            Border>
                        Viewbox>

                        <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Margin="10">
                            <TextBlock HorizontalAlignment="Center" Text="Loading..." Margin="0,0,0,15"/>
                            <TextBlock HorizontalAlignment="Center" Text="{TemplateBinding Description}" Margin="0,0,0,15"/>
                            <TextBlock HorizontalAlignment="Center" Text="{TemplateBinding Progress}" FontSize="{StaticResource TitleFontSize}" 
 FontWeight="Bold"/>
                        StackPanel>
                    Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsStart" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource PART\_Resource\_Storyboard}" x:Name="PART\_BeginStoryboard"/>
                            Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <StopStoryboard BeginStoryboardName="PART\_BeginStoryboard"/>
                            Trigger.ExitActions>
                        Trigger>

                    ControlTemplate.Triggers>
                ControlTemplate>
            Setter.Value>
        Setter>
    Style>

3)RingLoadingExample.xaml代码如下;

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.RingLoadingExample"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
 xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
 mc:Ignorable="d" 
 d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <wpfdev:RingLoading IsStart="true" 
 Width="400" Height="400"
 Description="WPFDevelopers" Foreground="Black" ProgressValue="50"/>
    Grid>
UserControl>

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

转载请注明:xuhss » 老板加薪!看我做的WPF Loading!!!

喜欢 (0)

您必须 登录 才能发表评论!