2009-10-16 3 views
6

Я добавляю немного анимации в свое приложение WPF.WPF - LayoutUpdated event firing again

Благодаря Dan Crevier's unique solution to animating the children of a panel в сочетании с awesome WPF Penner animations оказалось довольно простым, чтобы один из моих элементов управления выглядел великолепно, и его дети перемещаются с некоторой приятной анимацией.

К сожалению, все это связано с производительностью. Я рад, что производительность была удачной, когда элементы добавлены/удалены или элемент управления изменен, но кажется, что этот перфективный успех постоянно повторяется на протяжении всей жизни приложения, даже если элементы полностью статичны.

Класс PanelLayoutAnimator использует прикрепленное свойство для подключения события UIElement.LayoutUpdated. Когда это событие срабатывает, анимации рендеринга анимируются, чтобы заставить детей скользить к их новым позициям.

К сожалению, кажется, что событие LayoutUpdated срабатывает каждую секунду или около того, даже если в приложении ничего не происходит (по крайней мере, я не думаю, что мой код ничего не делает - приложение не имеет фокуса, а мышь устойчивый.) Поскольку причина события не сразу очевидна для обработчика событий, все дети контрольной группы должны быть переоценены. Это событие вызывается примерно раз в секунду при простоях. При использовании приложения частота увеличивается.

Так что мой вопрос в том, как я могу улучшить производительность здесь? Любой ответ, который помогает буду оценен, но я в настоящее время застрял на этом подвопросе:

  1. Что вызывает LayoutUpdated события стрелять так часто? Это должно произойти, а если нет, как я могу узнать, почему он стреляет и сворачивает его?

  2. Есть ли более удобный способ в обработчике узнать, произошло ли что-то, что могло бы переместить детей? Если это так, я могу выручить рано и избежать накладных расходов на цикл каждого ребенка.

Сейчас я буду работать вокруг этого вопроса путем отключения анимации при наличии более чем N детей в панели.

+0

Дрю, не могли бы вы поделиться небольшой пример кода, который может воспроизвести проблему? – Anvaka

+0

Да, потому что LayoutUpdated должен действительно срабатывать только в том случае, если что-то действительно вызывает обновление макета ... очевидно, как это звучит. :) Поскольку вы не взаимодействуете с окном, я не знаю, что могло бы вызвать это, кроме анимации, в измерениях, позициях или макете. –

+0

Хм приложение довольно большое. Если LayoutUpdated не должен регулярно запускаться, то какой метод я могу использовать, чтобы узнать, почему он стреляет? –

ответ

7

Если вы обновляете пользовательский интерфейс из EventHandler, подключенного к событию LayoutUpdated, это также инициирует это событие!

Например:

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!"); 
    } 
+2

Интересный момент, и это делает смысл. Я больше не работаю над этим приложением, но это звучит правдоподобно. Надеюсь, это поможет кому-то еще. –

+0

Можно ли проверить, какой пользовательский интерфейс обновлялся, вызывая недействительность? – simo