wpf 链式chain 故事板storyboard 导致 完播事件Completed多次执行无法Visibility的问题

本文讲述了在WPF中使用链式Storyboard时,遇到Completed事件多次执行的问题,通过设置Storyboard的FillBehavior属性为Stop解决了问题,解释了为何设置Stop可以阻止事件无限循环执行。
摘要由CSDN通过智能技术生成

wpf 链式chain 故事板storyboard 导致 完播事件Completed多次执行的问题

事件起因

最近用wpf做了个小应用,主要有多个storyboard链接交互,其中还有传感器采集等待。最明显的表象就是前一个故事播放完成后,无法通过Visibility.Collapsed/Hidden 隐藏,通过搜索重新element.Visibility = new Visibility();再隐藏也是无效。

尝试解决办法一

直接移除对象

     Storyboard sb3 = this.Resources["Storyboard3"] as Storyboard;
     sb3.Remove();

这个办法的确有效,但是只能对storyboard有效,如果是其它UI组件没法隐藏,因为多次执行而且还是异步的,导致比如要控制被事件控制过的组件,要点很多次才能执行到。

发现问题

通过在事件输出log发现,从第3个storyboard开始Completed事件开始以2的指数次执行

  • 第3个storyboard+=Completed 执行 2 次
  • 第4个storyboard+=Completed 执行 4 次
  • 第5个storyboard+=Completed 执行 8 次

正确的方法

增加FillBehavior="Stop",意思是完播后停止,该属性默认参数是Holdon意思是保持,在保持下无法修改storyboard控制的属性。

<Storyboard x:Key="Storyboard3" FillBehavior="Stop">

改成stop后确实没有多次执行了,但是为什么呢?

参考代码

前台

    <Page.Resources>
        <Storyboard x:Key="Storyboard1">
        </Storyboard>
        <Storyboard x:Key="Storyboard2">
        </Storyboard>
        <Storyboard x:Key="Storyboard3" FillBehavior="Stop">
        </Storyboard>
        <Storyboard x:Key="Storyboard4" FillBehavior="Stop">
        </Storyboard>
    </Page.Resources>

后台

private void myMedia_MediaEnded(object sender, RoutedEventArgs e)
{
   
    Console.WriteLine("播放结束");
    Storyboard sb = this.Resources["Storyboard1"] as Storyboard;
    sb.Completed += new EventHandler(StepOne);
    sb.Begin();
    }

}

private void StepOne(object sender, EventArgs e)
{
    Task task = Task.Run( () =>
    {
        try
        {
        //异步
        StepOneEnded();
           }
    });
}

private void StepOneEnded()
{
    _synchronizationContext.Send(new SendOrPostCallback(s =>
    {
        Storyboard sb2 = this.Resources["Storyboard2"] as Storyboard;
        sb2.Completed += new EventHandler(StepTwo);
        sb2.Begin();
    }), null);
}

private void StepTwo(object sender, EventArgs e)
{
    Task task = Task.Run( () =>
    {
        try
        {
            // 异步
        StepTwoEnded();
        }
}

// 没有FillBehavior="Stop"这里会执行2次
private void StepTwoEnded()
{
    _synchronizationContext.Send(new SendOrPostCallback(s =>
    {
        Storyboard sb3 = this.Resources["Storyboard3"] as Storyboard;
        sb3.Completed += new EventHandler(StepThreeEnd);
        sb3.Begin();

    }), null);
}

private void StepThreeEnd(object sender, EventArgs e)
{

    Storyboard sb4 = this.Resources["Storyboard4"] as Storyboard;
    sb4.Completed += new EventHandler(StepFourEnd);
    sb4.Begin();

}
// 没有FillBehavior="Stop"这里会执行4次
private void StepFourEnd(object sender, EventArgs e)
{

    Console.WriteLine("sssssssssssss");

}

欢迎哪位同学解释一下?

这是我搜到的,也就是说没有clock就会多次触发事件?:

I do not think it is caused by propertychanged event, I find you remove the clock object in completed event, I think there is no need to remove it, if you want to stop it, you could set “FillBehavior=“Stop”” in xaml, I remove below code snippet, your sample works:

Storyboard sb = this.FindResource("FadeInFadeOutStoryboard") as Storyboard;
 
            sb.Remove(StatusMessageBar);

参考url

  • 23
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值