網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
實(shí)現(xiàn)思路
框架使用大于等于.NET40
;
Visual Studio 2022
;
項(xiàng)目使用?MIT?開源許可協(xié)議;
老板覺得公司系統(tǒng)等待動(dòng)畫轉(zhuǎn)圈太簡(jiǎn)單,所以需要做一個(gè)稍微好看點(diǎn)的,就有這篇等待RingLoading動(dòng)畫
最外層使用Viewbox為父控件內(nèi)部嵌套創(chuàng)建三組?Grid -> Ellipse 、 Border
分別給它們指定不同的Angle從左側(cè)開始?-135 225 54
,做永久?Angle?動(dòng)畫;
-
PART_Ring1.RotateTransform.Angle從
From -135
?到?-495
; -
PART_Ring2.RotateTransform.Angle從
From 225
?到?-585
; -
PART_Ring3.RotateTransform.Angle從
From -54
?到?-315
;
如何繪制;
對(duì)Ellipse的StrokeDashArray進(jìn)行設(shè)置23 100就能達(dá)到效果;
Border?做為圓設(shè)置?Effect?可實(shí)現(xiàn)陰影效果;
實(shí)現(xiàn)代碼
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>
原文鏈接:https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal
相關(guān)推薦
- 2022-11-27 C語(yǔ)言三種函數(shù)調(diào)用約定_cdecl與_stdcall及_fastcall詳細(xì)講解_C 語(yǔ)言
- 2022-06-08 記一次網(wǎng)站全站http升級(jí)為https的過程,websocket : ws升級(jí)為wss遇到的問題等
- 2022-06-08 兩步配置解決 IDEA新項(xiàng)目maven依賴問題
- 2023-10-13 is using incorrect casing. Use PascalCase for Reac
- 2022-04-17 彈性布局 怎么讓某一列自適應(yīng)元素內(nèi)容的寬度
- 2022-11-04 C#序列化與反序列化集合對(duì)象并進(jìn)行版本控制_C#教程
- 2022-06-23 SQL?Server忘記sa賬號(hào)密碼重新添加新管理賬號(hào)_MsSql
- 2023-04-20 正則表達(dá)式:判斷是否符合USD格式
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支