WPF rotate an loading image for gif effect

前端 未结 2 1612
感动是毒
感动是毒 2020-12-22 12:28

I have a static loader image in wpf, I can easily use it as a loading gif by using WPFAnimatedGIF nuget package, but it seems like an overkill.

There is only one sce

相关标签:
2条回答
  • 2020-12-22 12:48

    I know that this question already has an answer, but there is a different approach. Just use ProgressBar and set IsIndeterminate to True:

    <ProgressBar Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}" Style="{StaticResource MaterialDesignCircularProgressBar}" IsIndeterminate="True" Width="36"/>
    

    The style is from Material Design In XAML Toolkit. There is no need to use GIFs as busy indicators, I made the same mistake some time ago

    0 讨论(0)
  • 2020-12-22 12:59

    This Style animates the Angle of a RotateTransform in 30 degree steps when the Image element is visible.

    <Style TargetType="Image" x:Key="BusyIndicatorStyle">
        <Setter Property="Width" Value="44"/>
        <Setter Property="Height" Value="44"/>
        <Setter Property="Source" Value="BusyIndicator.png"/>
        <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform/>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsVisible" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard RepeatBehavior="Forever">
                            <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetProperty="RenderTransform.Angle">
    
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.1" Value="30"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.2" Value="60"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.3" Value="90"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.4" Value="120"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.5" Value="150"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.6" Value="180"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.7" Value="210"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.8" Value="240"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:0.9" Value="270"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:1.0" Value="300"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:1.1" Value="330"/>
                                <DiscreteDoubleKeyFrame KeyTime="0:0:1.2" Value="360"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
        </Style.Triggers>
    </Style>
    
    ...
    <Image Style="{StaticResource BusyIndicatorStyle}" />
    

    In order to avoid using an animation with many DiscreteDoubleKeyFrames, you may derive from DoubleAnimation and add a Step property:

    public class DoubleAnimationWithSteps : DoubleAnimation
    {
        public static readonly DependencyProperty StepProperty = DependencyProperty.Register(
            nameof(Step), typeof(double), typeof(DoubleAnimationWithSteps));
    
        public double Step
        {
            get { return (double)GetValue(StepProperty); }
            set { SetValue(StepProperty, value); }
        }
    
        protected override double GetCurrentValueCore(
            double from, double to, AnimationClock animationClock)
        {
            var value = base.GetCurrentValueCore(from, to, animationClock);
    
            if (Step > 0d)
            {
                value = Step * Math.Floor(value / Step);
            }
    
            return value;
        }
    
        protected override Freezable CreateInstanceCore()
        {
            return new DoubleAnimationWithSteps();
        }
    }
    

    You would use it like this:

    <Storyboard RepeatBehavior="Forever">
        <local:DoubleAnimationWithSteps
            Storyboard.TargetProperty="RenderTransform.Angle"
            Duration="0:0:1.2" To="360" Step="30"/>
    </Storyboard>
    
    0 讨论(0)
提交回复
热议问题