WPF - 重复触发LayoutUpdated事件

Dre*_*kes 8 .net wpf layout animation panel

我一直在为我的WPF应用添加一些动画.

感谢Dan Crevier独特的解决方案,为小组的儿童制作了动画,并结合了令人敬畏的WPF Penner动画,结果让我的一个控件看起来很棒并且让孩子们用一些漂亮的动画来移动它是相当简单的.

不幸的是,这一切都带来了性能开销.我很高兴在添加/删除项目或调整控件时调整性能,但似乎这个性能在整个应用程序的生命周期内始终如一,即使项目完全是静态的.

所述PanelLayoutAnimator类使用附加属性来钩住UIElement.LayoutUpdated事件.当此事件触发时,渲染变换将被动画化以使子项滑动到新位置.

不幸的是LayoutUpdated,即使应用程序中没有发生任何事情,事件似乎每秒都会触发(至少我认为我的代码没有做任何事情 - 应用程序没有焦点,鼠标稳定.)事件的原因并不是事件处理程序立即明显的,控件的所有子项都必须重新评估.此事件在空闲时大约每秒调用一次.实际使用应用程序时频率会增加.

所以我的问题是,如何在这里提高性能?任何助攻的答案都会受到赞赏,但我现在仍然坚持这些子问题:

  1. 是什么导致LayoutUpdated事件频繁发生?这应该发生,如果没有,我怎么才能找出它为什么会开火并减少它?

  2. 在处理程序中是否有更方便的方法来了解是否发生了可能移动孩子的事情?如果是这样,我可以尽早摆脱困境,避免循环每个孩子.

现在,我将通过在面板中有超过N个子项时禁用动画来解决此问题.

小智 8

如果您从附加到LayoutUpdated事件的EventHandler更新UI,这也将触发该事件!

例如:

    void my_LayoutUpdatedEvent(object sender, EventArgs e)
    {
        textBlock1.Text = "changed";
        Console.Out.WriteLine("text changed!");
    }
Run Code Online (Sandbox Code Playgroud)

将进入无限循环的更新.

也许你需要做这样的事情:

    void my_BetterLayoutUpdatedEvent(object sender, EventArgs e)
    {
        if (!hasChanged)
            textBlock1.Text = "changed";
        hasChanged = true;
        Console.Out.WriteLine("text changed!");
    }
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,它是有道理的.我不再在那个应用程序上工作了,但这听起来似乎有道理.希望它可以帮助其他人. (2认同)