Продолжая серию ошибок для Silverlight 2, я хотел рассказать об общей ошибке, которую видят люди. Эта ошибка является чем-то новым, что вы можете увидеть при переносе кода из Beta 2 в Release Candidate или позже. В бета-версии 2, если механизм верстки обнаружил цикл, он не выдавал никаких ошибок; насколько я понимаю, макет был просто прерван. Но с битами после Beta2 выдается ошибка.
При появлении сообщения об ошибке в качестве сообщения будет указан «Layout Cycle Detected». Это сообщение об ошибке очень точное - механизм макета обнаружил цикл в вашем макете; или иначе, у вас есть бесконечный цикл в макете.
Самым большим виновником этой ошибки является код в обработчике событий LayoutUpdated. Если ваш обработчик событий LayoutUpdated что-либо изменит для макета вашего элемента управления, то это вызовет повторное инициирование события LayoutUpdated, и снова, и снова ...: -)
Иногда вам нужно иметь код, изменяющий компоновку в этом обработчике событий, так что же делать?
Во-первых, вы должны подумать, действительно ли вам нужно, чтобы изменения макета происходили при каждом вызове LayoutUpdated. Достаточно ли будет обработать событие Loaded, а также событие Application.Current.Host.Content.Resized. Между этими двумя событиями вы получите уведомление, когда элемент управления будет загружен в визуальное дерево, и вы будете получать уведомления каждый раз, когда размер хоста изменяется, что может потребовать повторного изменения макета. Сценарии, такие как модальные диалоги, должны попадать в эту категорию.
Во-вторых, если вам действительно нужно использовать LayoutUpdated, возможно, вам просто нужно наложить некоторые условия на изменения макета. Например, если вы рассчитываете новую ширину и высоту для своего элемента управления, прежде чем вы на самом деле установите ширину и высоту, убедитесь, что текущие значения отличаются от того, что вы рассчитали. Это позволит первому событию LayoutUpdated изменить размер вашего элемента управления, что вызовет другое событие LayoutUpdated, но это событие распознает, что не нужно выполнять никаких действий, и цикл завершится.
Эти же правила будут применяться при обработке события SizeChanged или при любых других переопределениях макета элемента управления.