01
—
效果预览
效果预览(更多效果请下载源码体验):
02
—
代码如下
一、CycleLoading.cs 代码如下
using System.Windows;
using System.Windows.Controls;
namespace WPFDevelopers.Controls
{
public class CycleLoading : ContentControl
{
static CycleLoading()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CycleLoading), new FrameworkPropertyMetadata(typeof(CycleLoading)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
public double MaxValue
{
get { return (double)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}
// Using a DependencyProperty as the backing store for MaxValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(double), typeof(CycleLoading), new PropertyMetadata(100d));
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double), typeof(CycleLoading), new PropertyMetadata(0d, OnValuePropertyChangedCallBack));
internal string ValueDescription
{
get { return (string)GetValue(ValueDescriptionProperty); }
set { SetValue(ValueDescriptionProperty, value); }
}
// Using a DependencyProperty as the backing store for ValueDescription. This enables animation, styling, binding, etc...
internal static readonly DependencyProperty ValueDescriptionProperty =
DependencyProperty.Register("ValueDescription", typeof(string), typeof(CycleLoading), new PropertyMetadata(default(string)));
private static void OnValuePropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is CycleLoading loading))
return;
if (!double.TryParse(e.NewValue?.ToString(), out double value))
return;
if (value >= loading.MaxValue)
{
value = loading.MaxValue;
if (loading.IsStart)
loading.IsStart = false;
}
else
{
if (!loading.IsStart)
loading.IsStart = true;
}
double dValue = value / loading.MaxValue;
loading.ValueDescription = dValue.ToString("P0");
}
public bool IsStart
{
get { return (bool)GetValue(IsStartProperty); }
set { SetValue(IsStartProperty, value); }
}
// 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(CycleLoading), new PropertyMetadata(true));
public string LoadTitle
{
get { return (string)GetValue(LoadTitleProperty); }
set { SetValue(LoadTitleProperty, value); }
}
// Using a DependencyProperty as the backing store for LoadTitle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LoadTitleProperty =
DependencyProperty.Register("LoadTitle", typeof(string), typeof(CycleLoading), new PropertyMetadata(default(string)));
}
}
二、CycleLoading.xaml 代码如下
<Style TargetType="{x:Type controls:CycleLoading}" BasedOn="{StaticResource ControlBasicStyle}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="30"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CycleLoading}">
<ControlTemplate.Resources>
<Storyboard x:Key="Storyboard_LoadRunning" RepeatBehavior="Forever" SpeedRatio="2">
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" Storyboard.TargetName="Part_Cycle_Rotate" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" Storyboard.TargetName="Part_Cycle_Rotate1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Viewbox>
<Grid Width="400" Height="400">
<Grid x:Name="Part_Cycle_Rotate1" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse Margin="0,50,0,50" >
<Ellipse.Fill>
<LinearGradientBrush >
<GradientStop Color="White" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
<Ellipse.Effect>
<BlurEffect Radius="40"/>
</Ellipse.Effect>
</Ellipse>
<Ellipse Margin="50,0,50,0" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="White" Offset="0.4" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
<Ellipse.Effect>
<BlurEffect Radius="40"/>
</Ellipse.Effect>
</Ellipse>
</Grid>
<Grid x:Name="Part_Cycle_Rotate" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse Margin="0,50,0,50" >
<Ellipse.Fill>
<LinearGradientBrush >
<GradientStop Color="#d495f1" Offset="0" />
<GradientStop Color="#87d3f7" Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
<Ellipse.Effect>
<BlurEffect Radius="15"/>
</Ellipse.Effect>
</Ellipse>
<Ellipse Margin="50,0,50,0" >
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#f173ac" Offset="0" />
<GradientStop Color="#33a3dc" Offset="1" />
</LinearGradientBrush>
</Ellipse.Fill>
<Ellipse.Effect>
<BlurEffect Radius="15"/>
</Ellipse.Effect>
</Ellipse>
</Grid>
<Ellipse Margin="33" Fill="Black" >
<Ellipse.Effect>
<DropShadowEffect BlurRadius="20" ShadowDepth="0" Color="White"/>
</Ellipse.Effect>
</Ellipse>
</Grid>
</Viewbox>
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" Text="{TemplateBinding LoadTitle}"/>
<ContentPresenter Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"/>
<TextBlock Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="15"
Text="{TemplateBinding ValueDescription}"/>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsStart" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Storyboard_LoadRunning}" x:Name="Storyboard_LoadRunning"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard_LoadRunning"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
三、RollLoading 代码如下
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WPFDevelopers.Controls
{
public class RollLoading : ContentControl
{
static RollLoading()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RollLoading), new FrameworkPropertyMetadata(typeof(RollLoading)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
public Color ForegroundColor
{
get { return (Color)GetValue(ForegroundColorProperty); }
set { SetValue(ForegroundColorProperty, value); }
}
// Using a DependencyProperty as the backing store for ForegroundColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ForegroundColorProperty =
DependencyProperty.Register("ForegroundColor", typeof(Color), typeof(RollLoading), new PropertyMetadata(Colors.Red));
public bool IsStart
{
get { return (bool)GetValue(IsStartProperty); }
set { SetValue(IsStartProperty, value); }
}
// 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(RollLoading), new PropertyMetadata(true));
}
}
四、RollLoading.xaml 代码如下
<Style TargetType="{x:Type controls:RollLoading}" BasedOn="{StaticResource ControlBasicStyle}">
<Setter Property="ForegroundColor" Value="{StaticResource DangerColor}"/>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:RollLoading}">
<ControlTemplate.Resources>
<Storyboard x:Key="RollKey" RepeatBehavior="Forever" >
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="2" Storyboard.TargetName="PART_Border1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="4" Storyboard.TargetName="PART_Border2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="6" Storyboard.TargetName="PART_Border3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="8" Storyboard.TargetName="PART_Border4" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="10" Storyboard.TargetName="PART_Border5" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="12" Storyboard.TargetName="PART_Border6" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="14" Storyboard.TargetName="PART_Border7" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<DoubleAnimation Duration="0:0:5" BeginTime="0" From="0" To="360" RepeatBehavior="Forever" SpeedRatio="16" Storyboard.TargetName="PART_Border8" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" />
<ColorAnimationUsingKeyFrames Duration="0:0:5" Storyboard.TargetProperty="ForegroundColor" RepeatBehavior="Forever">
<EasingColorKeyFrame KeyTime="0:0:0" Value="Red" EasingFunction="{StaticResource PowerEaseInOut}"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="Blue" EasingFunction="{StaticResource PowerEaseInOut}"/>
<EasingColorKeyFrame KeyTime="0:0:2" Value="Yellow" EasingFunction="{StaticResource PowerEaseInOut}"/>
<EasingColorKeyFrame KeyTime="0:0:3" Value="Green" EasingFunction="{StaticResource PowerEaseInOut}"/>
<EasingColorKeyFrame KeyTime="0:0:4" Value="Aqua" EasingFunction="{StaticResource PowerEaseInOut}"/>
<EasingColorKeyFrame KeyTime="0:0:5" Value="Red" EasingFunction="{StaticResource PowerEaseInOut}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Viewbox>
<Grid>
<Border x:Name="PART_Border1" Width="160" Height="160" BorderThickness="0,5,0,0" CornerRadius="80" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border2" Width="140" Height="140" BorderThickness="0,5,0,0" CornerRadius="70" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border3" Width="120" Height="120" BorderThickness="0,5,0,0" CornerRadius="60" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border4" Width="100" Height="100" BorderThickness="0,5,0,0" CornerRadius="50" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border5" Width="80" Height="80" BorderThickness="0,5,0,0" CornerRadius="40" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border6" Width="60" Height="60" BorderThickness="0,5,0,0" CornerRadius="30" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border7" Width="40" Height="40" BorderThickness="0,5,0,0" CornerRadius="20" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
<Border x:Name="PART_Border8" Width="20" Height="20" BorderThickness="0,5,0,0" CornerRadius="10" RenderTransformOrigin="0.5,0.5">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=ForegroundColor}" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.5"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
</Grid>
</Viewbox>
<ContentPresenter Grid.Row="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsStart" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="Roll_Storyboard" Storyboard="{StaticResource RollKey}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Roll_Storyboard"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
五、LoadingExample.xaml 代码如下
<wpfdev:CycleLoading Value="50" LoadTitle="Loading...." Width="200">
<TextBlock Text="activity"/>
</wpfdev:CycleLoading>
<wpfdev:RollLoading IsStart="true"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Width="200">
<TextBlock Text="Loading activity..."/>
</wpfdev:RollLoading>
源码地址
github:https://github.com/yanjinhuagood/WPFDevelopers.git
gitee:https://gitee.com/yanjinhua/WPFDevelopers.git
WPF开发者QQ群: 340500857
blogs: https://www.cnblogs.com/yanjinhua
Github:https://github.com/yanjinhuagood
出处:https://www.cnblogs.com/yanjinhua
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载请著名作者 出处 https://github.com/yanjinhuagood
技术群:添加小编微信并备注进群
小编微信:mm1552923
公众号:dotNet编程大全