C# WPF动画开始,但显示太晚

C# WPF动画开始,但显示太晚,c#,wpf,silverlight,animation,C#,Wpf,Silverlight,Animation,我正在使用.NET4.0构建一些WPF控件。其中一个名为LoadingPane的控件是从ContentControl派生的自定义控件。 此LoadingPane控件的唯一任务是在IsLoading属性设置为true时,在其包含的内容上显示半透明层。 我使用一些动画来进行淡入淡出,当IsLoading值更改时淡入淡出。 当显示叠加时,动画会旋转一圈省略号 到目前为止,一切顺利。这一切都非常有效。但我的问题是:当我将Loading属性设置为true时,动画不会直接显示。大约需要半秒钟。此时,淡入动画

我正在使用.NET4.0构建一些WPF控件。其中一个名为LoadingPane的控件是从ContentControl派生的自定义控件。 此LoadingPane控件的唯一任务是在IsLoading属性设置为true时,在其包含的内容上显示半透明层。 我使用一些动画来进行淡入淡出,当IsLoading值更改时淡入淡出。 当显示叠加时,动画会旋转一圈省略号

到目前为止,一切顺利。这一切都非常有效。但我的问题是:当我将Loading属性设置为true时,动画不会直接显示。大约需要半秒钟。此时,淡入动画已经运行,因此不透明度在一个步骤中有效地从0变为1

以下是我的动画代码:


奇怪的是,当我在测试窗口中使用此控件并反复单击加载复选框(在动画完成之前)时,淡入/淡出动画确实可以正常工作


有人能帮忙吗?先走一步

如果看不到代码的其余部分,很难准确地看出问题所在,但我猜这与动画属性的起始值有关

我在WPF中实现了一个自定义控件,在viewbox中有一个矩形,并使用问题中的触发器+故事板来查看效果。事实上,我的第一次尝试既没有淡入也没有淡出

为了解决这个问题,我在动画中指定了
From
值,这样无论DP的原始值是什么,它们都可以工作:

<DoubleAnimation BeginTime="00:00:00"
      Duration="00:00:00.5"
      Storyboard.TargetName="MyViewBoxje"
      Storyboard.TargetProperty="Opacity"
      From="0"
      To="1" />
ControlTemplate-以
{x:Type local:LoadingControl}

<ControlTemplate TargetType="{x:Type local:LoadingControl}">
    <ControlTemplate.Triggers>
        <Trigger Property="IsLoading" Value="True">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="EndAnimateLoadingCanvas" />
                <BeginStoryboard Name="AnimateLoadingCanvas">
                    <Storyboard FillBehavior="Stop">
                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
                                   Storyboard.TargetName="MyViewBoxje"
                                   Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
                        </ObjectAnimationUsingKeyFrames>

                        <DoubleAnimation BeginTime="00:00:00"
                                     Duration="00:00:00.5"
                                     Storyboard.TargetName="MyViewBoxje"
                                     Storyboard.TargetProperty="Opacity"
                                     From="0"
                                     To="1" />

                        <DoubleAnimation BeginTime="00:00:00"
                                         Duration="00:00:02"
                                         Storyboard.TargetName="AnimatedRotateTransform"
                                         Storyboard.TargetProperty="Angle"
                                         From="360"
                                         To="0"
                                         RepeatBehavior="Forever" />

                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="AnimateLoadingCanvas" />
                <BeginStoryboard Name="EndAnimateLoadingCanvas">
                    <Storyboard FillBehavior="Stop">
                        <DoubleAnimation BeginTime="00:00:00"
                                         Duration="00:00:00.5"
                                         Storyboard.TargetName="MyViewBoxje"
                                         Storyboard.TargetProperty="Opacity"
                                         From="1"
                                        To="0" />
                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00.5"
                                   Storyboard.TargetName="MyViewBoxje"
                                   Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" />
                        </ObjectAnimationUsingKeyFrames>

                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers>

    <Border Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
        <Viewbox x:Name="MyViewBoxje" Opacity="0">
            <!-- BG with 0x50 alpha so that it's translucent event at 100% visibility -->
            <Grid Width="100" Height="100" Background="#50000000">
                <Rectangle Width="70" Height="20" Fill="Green" Stroke="Black" StrokeThickness="2" RenderTransformOrigin="0.5,0.5">
                    <Rectangle.RenderTransform>
                        <RotateTransform Angle="360" x:Name="AnimatedRotateTransform" />
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Grid>
        </Viewbox>
    </Border>
</ControlTemplate>

读了伊萨克的答案后,我终于明白了。 很抱歉,他的回答对我没有帮助,但他让我走上了正确的方向

第一次淡入似乎不起作用的原因是,在执行淡入动画的整个过程中,我的包含视口的可见性设置为“折叠”。 这是由ObjectAnimationUsingKeyFrames引起的:

解决了我的问题


谢谢你们的帮助

我有着完全相同的问题(尽管是在不同的情况下)。我在加载Silverlight应用程序时运行的一个动画第一次从未显示过该动画。但随后的加载确实起了作用。终止并再次启动应用程序,我会得到相同的行为。从未找到答案,所以+1=)邦蒂补充道,也许我们可以通过这种方式得到答案。本质上,我认为问题在于如何防止加载动画被跳过,最好是在没有某种形式的解决方法的情况下,强制执行第一次阻止计时器事件?+1,如Smudge。SL也有同样的问题。为什么不使用BusyIndicator并按照自己的方式设计它呢?我认为这是围绕@Jehof.=)的一项工作我敢肯定,我们都见过一些网站和应用程序,当你加载它们时,它们是空白的或类似的,但随后页面的各个方面就会淡入人们的视野。我的观点是,这是一种时尚/专业的外观,而且令人讨厌的是,同样的效果不起作用,因为页面将在第一时间完全加载到视图中,没有褪色动画。也许答案是将某些方面移动到async?看起来是个赢家,不过如果您不介意发布完整的内容,那将是ace。我失败的silverlight项目(参考OP上的评论)我早就失去了控制。也许@Elad Katz也能证实吗?=)谢谢伊萨克,这将是一个方便的参考在未来。一旦赏金允许,我会给的。谢谢斯玛吉。很高兴我能帮上忙这对我来说并非如此,所以尽管我理解你将自己的答案作为答案,但我将把奖金奖励给伊萨克,因为他完整的例子似乎有效,如果我将来遇到同样的问题,这将是一个很好的参考。
<ControlTemplate TargetType="{x:Type local:LoadingControl}">
    <ControlTemplate.Triggers>
        <Trigger Property="IsLoading" Value="True">
            <Trigger.EnterActions>
                <RemoveStoryboard BeginStoryboardName="EndAnimateLoadingCanvas" />
                <BeginStoryboard Name="AnimateLoadingCanvas">
                    <Storyboard FillBehavior="Stop">
                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
                                   Storyboard.TargetName="MyViewBoxje"
                                   Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
                        </ObjectAnimationUsingKeyFrames>

                        <DoubleAnimation BeginTime="00:00:00"
                                     Duration="00:00:00.5"
                                     Storyboard.TargetName="MyViewBoxje"
                                     Storyboard.TargetProperty="Opacity"
                                     From="0"
                                     To="1" />

                        <DoubleAnimation BeginTime="00:00:00"
                                         Duration="00:00:02"
                                         Storyboard.TargetName="AnimatedRotateTransform"
                                         Storyboard.TargetProperty="Angle"
                                         From="360"
                                         To="0"
                                         RepeatBehavior="Forever" />

                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="AnimateLoadingCanvas" />
                <BeginStoryboard Name="EndAnimateLoadingCanvas">
                    <Storyboard FillBehavior="Stop">
                        <DoubleAnimation BeginTime="00:00:00"
                                         Duration="00:00:00.5"
                                         Storyboard.TargetName="MyViewBoxje"
                                         Storyboard.TargetProperty="Opacity"
                                         From="1"
                                        To="0" />
                        <ObjectAnimationUsingKeyFrames BeginTime="00:00:00.5"
                                   Storyboard.TargetName="MyViewBoxje"
                                   Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" />
                        </ObjectAnimationUsingKeyFrames>

                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers>

    <Border Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}">
        <Viewbox x:Name="MyViewBoxje" Opacity="0">
            <!-- BG with 0x50 alpha so that it's translucent event at 100% visibility -->
            <Grid Width="100" Height="100" Background="#50000000">
                <Rectangle Width="70" Height="20" Fill="Green" Stroke="Black" StrokeThickness="2" RenderTransformOrigin="0.5,0.5">
                    <Rectangle.RenderTransform>
                        <RotateTransform Angle="360" x:Name="AnimatedRotateTransform" />
                    </Rectangle.RenderTransform>
                </Rectangle>
            </Grid>
        </Viewbox>
    </Border>
</ControlTemplate>
<Grid x:Name="LayoutRoot">
    <!-- All other stuff here ... -->

    <my:LoadingControl IsLoading="{Binding IsLoading}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
public MainWindowViewModel()
{
    IsLoading = true;
    DispatcherTimer t = new DispatcherTimer();
    t.Interval = TimeSpan.FromSeconds(5);
    t.Tick += (s, e) => IsLoading = !IsLoading;
    t.Start();
}
    DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
Duration="00:00:00"