2016-12-07 6 views
0

tl; dr При добавлении детей к элементу - будут ли обновляться макеты детей при вызове theParent.UpdateLayout();?Обновляет ли UpdateLayout все дочерние элементы?

Longer версия

Мне нужно позвонить UpdateLayout на элемент, чтобы получить некоторую информацию о свойствах своего ребенка.

theParent.Children.Add(child); 
theParent.UpdateLayout(); 

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

ответ

1

Система макета по своей сути рекурсивна. Для того, чтобы кнопка автоматически настраивала себя в соответствии с ее содержимым, ей сначала нужно определить ее дочерние элементы (т. Е. Обычно метку TextBlock), и те элементы могут также нуждаться в том, чтобы их дочерние элементы тоже измерялись и т. Д.

Когда вы создаете новый UIElement, его макет изначально недействителен (или «грязный»). Это означает, что элемент отмечен как «необходимо выложить во время следующего цикла компоновки» - система макета будет пропускать элементы, которые не помечены как грязные, как оптимизация (макет дорог особенно для сложных визуальных деревьев).

Когда вы добавляете дочерний элемент на панель, панель делает недействительным, так как размер или положение панели могут быть затронуты ее дочерними элементами (true для StackPanel и Grid, но не для Canvas, я полагаю).

Важно понимать, что операции компоновки собраны. Поскольку прохождение макета является дорогостоящей операцией, оптимально отложить его до момента, когда не было больше обновлений для элементов. Представьте, добавили ли вы 100 элементов в ListView, а затем каждый раз выполняли 100 обновлений макета, он будет выполнять только 1 обновление в какой-то момент после добавления 100 элементов в список.

Во всяком случае, возвращаясь к вашему вопросу, называя UpdateLayout будет немедленно макета любой недействительных элементов в поддереве с корнем в элементе, который UpdateLayout был вызван вместо того, чтобы ждать, пока отложенную передачи макета.

Интересно, что документация говорит

UpdateLayout в основном эквивалентен вызову InvalidateMeasure и InvalidateArrange в последовательности.

, но, похоже, что это фактически недействительно, макет элемента был вызван, вместо этого он просто принудительно обновляет уже недействительные элементы (но это только мое наблюдение). Они используют «в принципе» очень слабо здесь.

Смежные вопросы