WPF - 重复触发 LayoutUpdated 事件

Posted

技术标签:

【中文标题】WPF - 重复触发 LayoutUpdated 事件【英文标题】:WPF - LayoutUpdated event firing repeatedly 【发布时间】:2010-12-07 07:52:12 【问题描述】:

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

感谢Dan Crevier's unique solution to animating the children of a panel 与awesome WPF Penner animations 的结合,结果证明让我的一个控件看起来很棒,并通过一些漂亮的动画让它的孩子四处走动。

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

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

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

所以我的问题是,我怎样才能提高这里的性能?任何有帮助的答案都将不胜感激,但我目前被困在这些子问题上:

    是什么导致LayoutUpdated 事件如此频繁地触发?这应该发生吗?如果不是,我怎样才能找出它为什么会触发并减少它?

    在处理程序中是否有更方便的方法来了解是否发生了可能让孩子感动的事情?如果是这样,我可以提前退出并避免循环每个孩子的开销。

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

【问题讨论】:

Drew,你能分享一下可以重现问题的小代码示例吗? 是的,因为 LayoutUpdated 应该只有在确实导致布局更新时才会触发......听起来很明显。 :) 由于您没有与 Window 进行交互,我不知道除了尺寸、位置或布局变换的动画之外会触发什么。 嗯,应用程序相当大。如果 LayoutUpdated 不应该定期触发,那么我可以使用什么技术来找出它触发的原因? 我还可以指出,我在表单中使用了 WinForms ElementHost 这个清除了原因并给出了更好的解决方案:-> blogs.msdn.microsoft.com/devdave/2008/05/27/… 【参考方案1】:

如果您从附加到 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!");

【讨论】:

有趣的一点,这很有意义。我不再为那个应用程序工作,但这听起来很合理。希望它可以帮助其他人。 是否可以检查导致失效的 UI 更新?

以上是关于WPF - 重复触发 LayoutUpdated 事件的主要内容,如果未能解决你的问题,请参考以下文章

仅在 C#/WPF 中的给定时间内未触发事件时才执行事件 [重复]

WPF DataGrid 如何动态设置单行高度

WPF中样式和行为和触发器

WPF Datagrid 行编辑“ENDED”事件

WPF触发器

WPF中ListBox连续选择同一项时SelectionChanged 事件不响应的问题