凑合用吧,wpf的loading动画挺多的,好不容易自己写了点得记下来。
记在别的地方还容易找不到,就记在这里吧。。
先放几个图,gif弄起来太麻烦了,我直接截图吧,1-》2-》3-》1-》2-》3这样看,眨眼补帧就好。
xaml:
<Style TargetType="{x:Type cc:Loading}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:Loading}">
<Border>
<Border.Resources>
<Storyboard x:Key="BaseEllipseAnimation" RepeatBehavior="Forever">
<!-- 透明度动画 -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="1" />
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="0.8" />
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="1" />
</DoubleAnimationUsingKeyFrames>
<!-- 宽度动画 -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="5" />
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</DoubleAnimationUsingKeyFrames>
<!-- 高度动画 -->
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)">
<SplineDoubleKeyFrame KeyTime="0:0:0" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="5" />
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="EllipseAnimation1" BeginTime="0:0:0.0">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation2" BeginTime="0:0:0.25">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation3" BeginTime="0:0:0.5">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation4" BeginTime="0:0:0.75">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation5" BeginTime="0:0:1.0">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation6" BeginTime="0:0:1.25">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation7" BeginTime="0:0:1.50">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
<Storyboard x:Key="EllipseAnimation8" BeginTime="0:0:1.75">
<StaticResource ResourceKey="BaseEllipseAnimation"/>
</Storyboard>
</Border.Resources>
<Border.Background>
<SolidColorBrush Color="Black" Opacity=".8" />
</Border.Background>
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<cc:CirclePanel HorizontalAlignment="Center">
<cc:CirclePanel.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Width" Value="{Binding Size, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<Setter Property="Height" Value="{Binding Size, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</Style>
<Style TargetType="{x:Type Ellipse}">
<Setter Property="Margin" Value="0" />
<Setter Property="Width" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<Setter Property="Height" Value="{Binding Diameter,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<Setter Property="Fill" Value="{Binding FillBrush,RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</Style>
</cc:CirclePanel.Resources>
<Border>
<Ellipse Name="e1" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation1}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e2">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation2}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e3" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation3}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e4" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation4}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e5" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation5}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e6" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation6}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e7" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation7}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
<Border>
<Ellipse Name="e8" >
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Ellipse.Loaded">
<BeginStoryboard Storyboard="{StaticResource EllipseAnimation8}"/>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
</Border>
</cc:CirclePanel>
<TextBlock Foreground="White" Text="{Binding Text, RelativeSource={RelativeSource Mode=TemplatedParent}}" Margin="0,30,0,5" />
</StackPanel>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
cs:
internal class Loading : UserControl
{
public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register(nameof(Size), typeof(double), typeof(Loading), new PropertyMetadata(5.0, OnSizePropertyChanged));
private static void OnSizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Loading loading)
{
loading.Diameter = (double)e.NewValue / 2d;
}
}
public double Size
{
get { return (double)GetValue(SizeProperty); }
set { SetCurrentValue(SizeProperty, value); }
}
public double Diameter { get; set; }
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string), typeof(Loading), new PropertyMetadata(null, OnTextPropertyChanged));
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Loading loading)
{
loading.Text = e.NewValue as string;
}
}
public string Text
{
get { return (string)GetValue(SizeProperty); }
set { SetCurrentValue(TextProperty, value); }
}
public static readonly DependencyProperty FillBrushProperty =
DependencyProperty.Register(nameof(FillBrush), typeof(System.Windows.Media.Brush), typeof(Loading), new PropertyMetadata(Brushes.Blue));
public System.Windows.Media.Brush FillBrush
{
get { return (System.Windows.Media.Brush)GetValue(FillBrushProperty); }
set { SetCurrentValue(FillBrushProperty, value); }
}
static Loading()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Loading), new FrameworkPropertyMetadata(typeof(Loading)));
}
}