WPF-запуск события LayoutUpdated повторно

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

спасибо уникальное решение Дэна Кревье для анимации детей панели в сочетании с удивительный WPF Пеннер анимации оказалось, что довольно просто сделать один из моих элементов управления большим и заставить его детей двигаться с некоторой приятной анимацией.

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

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

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

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

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

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

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

1 ответов


Если вы обновляете пользовательский интерфейс из 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!");
    }