WPF loading spinner

后端 未结 14 791
我寻月下人不归
我寻月下人不归 2020-12-02 05:30

The goal is to display the information that the application is working. So I\'m looking for an intelligent implementation sample of a loading spinner using WPF / MVVM.

相关标签:
14条回答
  • 2020-12-02 05:59

    This is an update to the code given by @HAdes to parameterize width, height, and ellipse size.

    This implementation automatically calculates required angles, widths, and heights on the fly.

    The user control is bound to itself (code-behind) which takes care of all calculations.

    XAML

    <UserControl x:Class="WpfApplication2.Spinner"
                 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:local="clr-namespace:WpfApplication2"
                 mc:Ignorable="d" 
                 DataContext="{Binding RelativeSource={RelativeSource Self}}"
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <Color x:Key="FilledColor" A="255" B="155" R="155" G="155"/>
            <Color x:Key="UnfilledColor" A="0" B="155" R="155" G="155"/>
    
            <Style x:Key="BusyAnimationStyle" TargetType="Control">
                <Setter Property="Background" Value="Transparent"/>
    
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Control">
                            <ControlTemplate.Resources>
                                <Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseN" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseNE" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseE" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseSE" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseS" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseSW" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseW" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
    
                                <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipseNW" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </ControlTemplate.Resources>
    
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsVisible" Value="True">
                                    <Trigger.EnterActions>
                                        <BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
                                        <BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
                                        <BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
                                    </Trigger.EnterActions>
    
                                    <Trigger.ExitActions>
                                        <StopStoryboard BeginStoryboardName="Storyboard0"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard1"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard2"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard3"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard4"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard5"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard6"/>
                                        <StopStoryboard BeginStoryboardName="Storyboard7"/>
                                    </Trigger.ExitActions>
                                </Trigger>
                            </ControlTemplate.Triggers>
    
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                                <Grid>
                                    <Canvas>
                                        <Canvas.Resources>
                                            <Style TargetType="Ellipse">
                                                <Setter Property="Width" Value="{Binding Path=EllipseSize}"/>
                                                <Setter Property="Height" Value="{Binding Path=EllipseSize}" />
                                                <Setter Property="Fill" Value="Transparent" />
                                            </Style>
                                        </Canvas.Resources>
    
                                        <Ellipse x:Name="ellipseN" Canvas.Left="{Binding Path=EllipseN.Left}" Canvas.Top="{Binding Path=EllipseN.Top}"/>
                                        <Ellipse x:Name="ellipseNE" Canvas.Left="{Binding Path=EllipseNE.Left}" Canvas.Top="{Binding Path=EllipseNE.Top}"/>
                                        <Ellipse x:Name="ellipseE" Canvas.Left="{Binding Path=EllipseE.Left}" Canvas.Top="{Binding Path=EllipseE.Top}"/>
                                        <Ellipse x:Name="ellipseSE" Canvas.Left="{Binding Path=EllipseSE.Left}" Canvas.Top="{Binding Path=EllipseSE.Top}"/>
                                        <Ellipse x:Name="ellipseS" Canvas.Left="{Binding Path=EllipseS.Left}" Canvas.Top="{Binding Path=EllipseS.Top}"/>
                                        <Ellipse x:Name="ellipseSW" Canvas.Left="{Binding Path=EllipseSW.Left}" Canvas.Top="{Binding Path=EllipseSW.Top}"/>
                                        <Ellipse x:Name="ellipseW" Canvas.Left="{Binding Path=EllipseW.Left}" Canvas.Top="{Binding Path=EllipseW.Top}"/>
                                        <Ellipse x:Name="ellipseNW" Canvas.Left="{Binding Path=EllipseNW.Left}" Canvas.Top="{Binding Path=EllipseNW.Top}"/>
    
                                    </Canvas>
                                    <Label Content="{Binding Path=Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </UserControl.Resources>
        <Border>
            <Control Style="{StaticResource BusyAnimationStyle}"/>
        </Border>
    </UserControl>
    

    Code Behind (C#)

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApplication2
    {
        /// <summary>
        /// Interaction logic for Spinner.xaml
        /// </summary>
        public partial class Spinner : UserControl
        {
            public int EllipseSize { get; set; } = 8;
            public int SpinnerHeight { get; set; } = 0;
            public int SpinnerWidth { get; set; } = 0;
    
    
            // start positions
            public EllipseStartPosition EllipseN { get; private set; }
            public EllipseStartPosition EllipseNE { get; private set; }
            public EllipseStartPosition EllipseE { get; private set; }
            public EllipseStartPosition EllipseSE { get; private set; }
            public EllipseStartPosition EllipseS { get; private set; }
            public EllipseStartPosition EllipseSW { get; private set; }
            public EllipseStartPosition EllipseW { get; private set; }
            public EllipseStartPosition EllipseNW { get; private set; }
    
            public Spinner()
            {
                InitializeComponent();
            }
    
            private void initialSetup()
            {
                float horizontalCenter = (float)(SpinnerWidth / 2);
                float verticalCenter = (float)(SpinnerHeight / 2);
                float distance = (float)Math.Min(SpinnerHeight, SpinnerWidth) /2;
    
                double angleInRadians = 44.8;
                float cosine = (float)Math.Cos(angleInRadians);
                float sine = (float)Math.Sin(angleInRadians);
    
                EllipseN = newPos(left: horizontalCenter, top: verticalCenter - distance);
                EllipseNE = newPos(left: horizontalCenter + (distance * cosine), top: verticalCenter - (distance * sine));
                EllipseE = newPos(left: horizontalCenter + distance, top: verticalCenter);
                EllipseSE = newPos(left: horizontalCenter + (distance * cosine), top: verticalCenter + (distance * sine));
                EllipseS = newPos(left: horizontalCenter, top: verticalCenter + distance);
                EllipseSW = newPos(left: horizontalCenter - (distance * cosine), top: verticalCenter + (distance * sine));
                EllipseW = newPos(left: horizontalCenter - distance, top: verticalCenter);
                EllipseNW = newPos(left: horizontalCenter - (distance * cosine), top: verticalCenter - (distance * sine));
            }
    
            private EllipseStartPosition newPos(float left, float top)
            {
                return new EllipseStartPosition() { Left = left, Top = top };
            }
    
            
            protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
            {
                if(e.Property.Name == "Height")
                {
                    SpinnerHeight = Convert.ToInt32(e.NewValue);
                }
    
                if (e.Property.Name == "Width")
                {
                    SpinnerWidth = Convert.ToInt32(e.NewValue);
                }
    
                if(SpinnerHeight > 0 && SpinnerWidth > 0)
                {
                    initialSetup();
                }
    
                base.OnPropertyChanged(e);
            }
        }
    
        public struct EllipseStartPosition
        {
            public float Left { get; set; }
            public float Top { get; set; }
        }
    }
    

    Sample Use

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication2"
            xmlns:animated="WpfApplication2.MainWindow"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
    
        <StackPanel Background="DarkGoldenrod" Width="200" Height="200" VerticalAlignment="Top" HorizontalAlignment="Left" >
            <Button Height="35">
                <Button.Content >
                    <DockPanel LastChildFill="True" Height="NaN" Width="NaN" HorizontalAlignment="Left">
                        <local:Spinner EllipseSize="4" DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="0,0,10,5" Height="16" Width="16"/>
                        <TextBlock Text="Cancel" VerticalAlignment="Center"/>
                    </DockPanel>
                </Button.Content>
            </Button>
    
        </StackPanel>
    
    </Window>
    
    0 讨论(0)
  • 2020-12-02 06:00

    use an enum type to indicate your ViewModel's State

    public enum ViewModeType
    {
        Default, 
        Busy
        //etc.
    }
    

    then in your ViewModels Base class use a property

    public ViewModeType ViewMode
    {
        get { return this.viewMode; }
        set
        {
            if (this.viewMode != value)
            {
                this.viewMode = value;
                                //You should notify property changed here
            }
        }
    }
    

    and in view trigger the ViewMode and if it is busy show busyindicator:

    <Trigger Property="ViewMode" Value="Busy">
        <!-- Show BusyIndicator -->
    </Trigger>
    
    0 讨论(0)
  • 2020-12-02 06:04

    The approach is to use geometry with animations applied. Add the required geometry to the Path and animate its RotateTransform from 0-360°.

    My spinner support two types of spinners:

    1. Circles :
    2. Rings :

    And the central logic looks like:

    if(spinner.SpinnerType == SpinnerType.Ring)
    {
     double innerRad = spinner.Radius - spinner.ItemRadius;
     Point center = new Point(0, 0);
     grp.Children.Add(new EllipseGeometry( center, spinner.Radius, spinner.Radius));
     grp.Children.Add(new EllipseGeometry(center, innerRad, innerRad));                
     return;
    }
    var points = GetPointsOnCircle( spinner.Diameter/ 2);
    double r = spinner.ItemRadius;
    foreach (var point in points)
    {
     grp.Children.Add(new EllipseGeometry(point, r, r));
     r -= spinner.ContinuousSizeReduction;
    }
    

    Usage is as simple as follows:

    <local:SpinnerControl Diameter="60" Fill="#FFE8B311"/>

    Here is the source code!

    0 讨论(0)
  • 2020-12-02 06:07

    The customized spinner posted by @Menol had a small issue where the spinner would be shifted down and to the right by the size of one dot. I have updated the code so that it compensates for this offset by subtracting by half the dot.

    Here is the updated code:

        private void initialSetup()
        {
            float horizontalCenter = (float)(SpinnerWidth / 2);
            float verticalCenter = (float)(SpinnerHeight / 2);
            float distance = (float)Math.Min(SpinnerHeight, SpinnerWidth) / 2;
            float dotComp = (float)(EllipseSize / 2);
    
            double angleInRadians = 44.8;
            float cosine = (float)Math.Cos(angleInRadians);
            float sine = (float)Math.Sin(angleInRadians);
    
            EllipseN = newPos(left: horizontalCenter - dotComp, top: verticalCenter - distance - dotComp);
            EllipseNE = newPos(left: horizontalCenter + (distance * cosine) - dotComp, top: verticalCenter - (distance * sine) - dotComp);
            EllipseE = newPos(left: horizontalCenter + distance - dotComp, top: verticalCenter - dotComp);
            EllipseSE = newPos(left: horizontalCenter + (distance * cosine) - dotComp, top: verticalCenter + (distance * sine) - dotComp);
            EllipseS = newPos(left: horizontalCenter - dotComp, top: verticalCenter + distance - dotComp);
            EllipseSW = newPos(left: horizontalCenter - (distance * cosine) - dotComp, top: verticalCenter + (distance * sine) - dotComp);
            EllipseW = newPos(left: horizontalCenter - distance - dotComp, top: verticalCenter - dotComp);
            EllipseNW = newPos(left: horizontalCenter - (distance * cosine) - dotComp, top: verticalCenter - (distance * sine) - dotComp);
        }
    
    0 讨论(0)
  • 2020-12-02 06:10

    With Images

    Visual summary of options for spinning icons. Recorded using Screen To Gif.


    Font-Awesome-WPF

    Documentation on GitHub.

    Install via NuGet:

    PM> Install-Package FontAwesome.WPF

    Looks like this:

    XAML:

    <fa:ImageAwesome Icon="Spinner" Spin="True" SpinDuration="4" />
    

    Icons pictured are Spinner, CircleOutlineNotch, Refresh and Cog. There are many others.


    Method from @HAdes

    XAML copy/paste.

    0 讨论(0)
  • 2020-12-02 06:14

    To get this:

    Stick this in a user control:

    <UserControl.Resources>
        <Color x:Key="FilledColor" A="255" B="155" R="155" G="155"/>
        <Color x:Key="UnfilledColor" A="0" B="155" R="155" G="155"/>
    
        <Style x:Key="BusyAnimationStyle" TargetType="Control">
            <Setter Property="Background" Value="#7F000000"/>
    
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Control">
                        <ControlTemplate.Resources>
                            <Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
    
                            <Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                    <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
                                    <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>
    
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsVisible" Value="True">
                                <Trigger.EnterActions>
                                    <BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
                                    <BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
                                    <BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
                                </Trigger.EnterActions>
    
                                <Trigger.ExitActions>
                                    <StopStoryboard BeginStoryboardName="Storyboard0"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard1"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard2"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard3"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard4"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard5"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard6"/>
                                    <StopStoryboard BeginStoryboardName="Storyboard7"/>
                                </Trigger.ExitActions>
                            </Trigger>
                        </ControlTemplate.Triggers>
    
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <Grid>
                            <Canvas Height="60" Width="60">
                                <Canvas.Resources>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Width" Value="15"/>
                                        <Setter Property="Height" Value="15" />
                                        <Setter Property="Fill" Value="#009B9B9B" />
                                    </Style>
                                </Canvas.Resources>
    
                                <Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
                                <Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
                                <Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
                                <Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
                                <Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
                                <Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
                                <Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
                                <Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
                                <Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>
                            </Canvas>
                                <Label Content="{Binding Path=Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Control Style="{StaticResource BusyAnimationStyle}"/>
    

    To get a cool disappearing effect on each ellipse add the following after each ColorAnimationUsingKeyFrames element. Be sure to point it to the correct ellipse..

    <ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
        <SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
        <SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
    </ColorAnimationUsingKeyFrames>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="Width" >
        <DoubleAnimationUsingKeyFrames.KeyFrames>
            <SplineDoubleKeyFrame  KeyTime="00:00:00.0" Value="15" />
            <SplineDoubleKeyFrame  KeyTime="00:00:01.0" Value="12" />
            <SplineDoubleKeyFrame  KeyTime="00:00:01.6" Value="0" />
        </DoubleAnimationUsingKeyFrames.KeyFrames>
    </DoubleAnimationUsingKeyFrames>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="Height" >
        <DoubleAnimationUsingKeyFrames.KeyFrames>
            <SplineDoubleKeyFrame  KeyTime="00:00:00.0" Value="15" />
            <SplineDoubleKeyFrame  KeyTime="00:00:01.0" Value="12" />
            <SplineDoubleKeyFrame  KeyTime="00:00:01.6" Value="0" />
        </DoubleAnimationUsingKeyFrames.KeyFrames>
    </DoubleAnimationUsingKeyFrames>
    
    0 讨论(0)
提交回复
热议问题