反复LayoutUpdated事件射击 - WPF事件、LayoutUpdated、WPF

2023-09-03 01:01:07 作者:穿着军服逛网吧。

我已经增加了一点的动画到我的WPF应用程序。

I've been adding a bit of animation to my WPF application.

感谢Dan Crevier独特的解决方案,以动画面板的孩子的结合真棒WPF彭纳动画这竟然是相当简单的,使我的控制很好看之一,有其子走动了一些漂亮的动画。

Thanks to Dan Crevier's unique solution to animating the children of a panel combined with the awesome WPF Penner animations it turned out to be fairly straightforward to make one of my controls look great and have its children move about with some nice animation.

不幸的是这一切都配有性能开销。我很高兴能有性能损失,当项目被添加/删除或调整控件大小,但似乎这个PERF的命中始终发生在整个应用程序的生命周期,即使项目是完全静态的。

Unfortunately this all comes with a performance overhead. I'm happy to have the performance hit when items are added/removed or the control is resized, but it seems that this perf hit occurs consistently throughout the application's lifetime, even when items are completely static.

PanelLayoutAnimator 类使用附加属性挂钩的UIElement.LayoutUpdated事件。当这个事件触发,使得变换的动画,使孩子们滑行到他们的新岗位。

The PanelLayoutAnimator class uses an attached property to hook the UIElement.LayoutUpdated event. When this event fires, render transforms are animated to cause the children to glide to their new positions.

不幸的是,似乎 LayoutUpdated 事件触发每一秒左右,甚至当什么也没发生在应用程序中(至少我不认为我的code的做任何事情 - 应用程序没有焦点并且鼠标稳定),而对于事件的原因不能立即到事件处理程序明显,控制的所有儿童都必须重新评估。此事件被称为约每秒一次空闲时。在实际使用的应用程序的频率增加了。

Unfortunately it seems that the LayoutUpdated event fires every second or so, even when nothing is happening in the application (at least I don't think my code's doing anything -- the app doesn't have focus and the mouse is steady.) As the reason for the event is not immediately apparent to the event handler, all children of the control have to be reevaluated. This event is being called about once a second when idle. The frequency increases when actually using the app.

所以我的问题是,我怎么能提高性能吗?任何答案,帮助将AP preciated,但我目前停留在这些子问题:

So my question is, how can I improve the performance here? Any answer that assists would be appreciated, but I'm currently stuck on these sub-questions:

是什么原因导致了 LayoutUpdated 触发事件,如此频繁?这是应该发生的,如果没有,我怎么能找出为什么它的发射,并限制呢?

What causes the LayoutUpdated event to fire so frequently? Is this supposed to happen, and if not, how can I find out why it's firing and curtail it?

有没有处理程序中更方便的方法知道的东西是否已经发生,可能有感动的孩子?如果是这样,我能摆脱困境的早期,避免循环每个孩子的开销。

Is there a more convenient way within the handler to know whether something has happened that might have moved children? If so, I could bail out early and avoid the overhead of looping each child.

现在,我会解决此问题通过禁用动画时,有超过的 N 的面板中的孩子。

For now I will work around this issue by disabling animation when there are more than N children in the panel.

推荐答案

如果您要更新从您连接到LayoutUpdated事件的事件处理程序的用户界面,这也将触发该事件!

If you're updating the UI from the EventHandler you attached to the LayoutUpdated event, this will also trigger that event!

例如:

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

将进入更新的无限循环。

will go into an infinite loop of updates.

也许你需要做的是这样的:

Perhaps you need to do something like this:

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