11

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

多亏了Dan Crevier 独特的解决方案来为面板的子级设置动画,并结合了令人敬畏的 WPF Penner 动画,结果证明让我的一个控件看起来很棒并让其子级通过一些漂亮的动画移动非常简单。

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

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

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

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

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

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

现在我将通过在面板中有N个以上的孩子时禁用动画来解决这个问题。

4

1 回答 1

10

如果您要从EventHandler附加到LayoutUpdated事件的 UI 中更新 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!");
}
于 2012-07-16T19:11:30.190 回答