重复故事板转换一定次数

本文关键字:转换 故事 | 更新日期: 2023-09-27 17:50:48

我正在尝试在Windows Phone 8中实现对ButtonTextBlock元素的不透明度过渡。

这些是我要转换的ButtonTextBlock元素:

<Button
                x:Name="letterHole" 
                Width="230"
                Height="387"
                Opacity="0"
                BorderThickness="0"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Click="letterHole_Click">
                <Button.Background>
                    <ImageBrush ImageSource="/Assets/Main/letterHoleBackground@2x.png"/>
                </Button.Background>
            </Button>
            <TextBlock
                Name="letter"
                Text=""
                FontSize="60"
                TextAlignment="Center"
                Foreground="Blue"
                Margin="378,268,376,109"/>

Button有一个背景图像,TextBlock位于它的顶部。

这些是我正在使用的故事板过渡:

        <Storyboard x:Name="fadeInAnimation">
            <DoubleAnimation
                Storyboard.TargetName="letterHole"
                Storyboard.TargetProperty="Opacity"
                From="0.0" To="1.0" Duration="0:0:1"/>
        </Storyboard>
        <Storyboard x:Name="wait">
            <DoubleAnimation
                Storyboard.TargetName="letterHole"
                Storyboard.TargetProperty="Opacity"
                From="1.0" To="1.0" Duration="0:0:2"/>
        </Storyboard>
        <Storyboard x:Name="fadeOutAnimation">
            <DoubleAnimation
                Storyboard.TargetName="letterHole"
                Storyboard.TargetProperty="Opacity"
                From="1.0" To="0.0" Duration="0:0:1"/>
        </Storyboard>

我按以下顺序运行它们:fadeInAnimation, wait, fadeOutAnimation,结果是元素淡入,等待2秒,然后淡出。

我想让这个动画序列重复一定次数,现在是6次,每次重复都改变TextBlockText属性。

这是我使用的c#代码:

    public ConstructorOfClass()
    {
        InitializeComponent();
        string[] letters = {"A", "B", "C", "D", "E", "F"};
        int i = 0;
        int show = 6;
        animate();
    }
    private void animate()
    {
        if(show > 0)
        {
            fadeInAnimation.Begin();
            fadeInAnimation.Completed += fadeInAnimation_Completed;
        }
    }
    private void fadeInAnimation_Completed(object sender, EventArgs e)
    {
        letter.Text = letters[i];
        wait.Begin();
        wait.Completed += wait_Completed;
    }
    private void wait_Completed(object sender, EventArgs e)
    {
        fadeOutAnimation.Begin();
        fadeOutAnimation.Completed +=fadeOutAnimation_Completed;
    }
    private void fadeOutAnimation_Completed(object sender, EventArgs e)
    {
        show--;
        i++;
        animate();
    }

我已经添加了一些变量:

int show -重复次数

int i - letters[]数组的索引

每重复一次必须显示一个新字母。

这个问题ishow不按我计划的方式增加,所以在2-3次重复后,show下降到0。

此外,在尝试调试问题后,我注意到在fadeOutAnimation_Completed()方法中有时animate()方法没有被调用,导致由于某种原因ishow再次增加2或3倍。

我错过了什么?

重复故事板转换一定次数

每次wait完成后,

fadeOutAnimation.Completed += fadeOutAnimation_Completed;

这意味着fadeOutAnimation_Completed将在第一次运行期间被调用一次,在第二次运行期间被调用两次,在第三次运行期间被调用3次,所以如果你在第一次运行后开始使用show = 6,它将是5,第二次运行3和第3次运行将是0。我认为你在3个故事板中做的事情在2个故事板中也可以做到如果你在第二个故事板中使用BeginTime:

<Storyboard x:Name="fadeInAnimation" Completed="fadeInAnimation_Completed">
    <DoubleAnimation 
        From="0" 
        To="1" 
        Storyboard.TargetProperty="Opacity" 
        Storyboard.TargetName="letterHole" 
        Duration="0:0:1"/>                
</Storyboard>
<Storyboard x:Name="fadeOutAnimation" Completed="fadeOutAnimation_Completed">
    <DoubleAnimation 
        From="1" 
        To="0" 
        Storyboard.TargetProperty="Opacity" 
        Storyboard.TargetName="letterHole" 
        Duration="0:0:1" 
        BeginTime="0:0:3"/>
</Storyboard>

代码的问题在于您多次订阅了StoryboardsCompleted事件(每次执行Completed事件时,您都重新订阅了下一个故事板的Completed事件,这意味着下次它再执行一次)。

您应该简单地从XAML:

订阅完成的事件。
<Storyboard x:Name="fadeInAnimation" Completed="fadeInAnimation_Completed">
    <DoubleAnimation
        Storyboard.TargetName="letterHole"
        Storyboard.TargetProperty="Opacity"
        From="0.0" To="1.0" Duration="0:0:1"/>
</Storyboard>
<Storyboard x:Name="wait" Completed="wait_Completed">
    <DoubleAnimation
        Storyboard.TargetName="letterHole"
        Storyboard.TargetProperty="Opacity"
        From="1.0" To="1.0" Duration="0:0:2"/>
</Storyboard>
<Storyboard x:Name="fadeOutAnimation" Completed="fadeOutAnimation_Completed">
    <DoubleAnimation
        Storyboard.TargetName="letterHole"
        Storyboard.TargetProperty="Opacity"
        From="1.0" To="0.0" Duration="0:0:1"/>
</Storyboard>

然后在你的代码后面(我只是删除了事件订阅):

private void animate()
{
    if (show > 0)
    {
        fadeInAnimation.Begin();
    }
}
private void fadeInAnimation_Completed(object sender, EventArgs e)
{
    letter.Text = letters[i];
    wait.Begin();
}
private void wait_Completed(object sender, EventArgs e)
{
    fadeOutAnimation.Begin();
}
private void fadeOutAnimation_Completed(object sender, EventArgs e)
{
    show--;
    i++;
    animate();
}