WPF - 重复触发LayoutUpdated事件

时间:2009-10-16 10:12:01

标签: .net wpf layout animation panel

我一直在为我的WPF应用程序添加一些动画。

感谢Dan Crevier's unique solution to animating the children of a panelawesome WPF Penner animations相结合,结果让我的一个控件看起来很棒并且让它的孩子用一些漂亮的动画来移动。

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:8)

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

例如:

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

将进入无限循环的更新。

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

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