Silverlight错误“检测到布局周期的布局无法完成​​".使用自定义控件时 [英] Silverlight Error "Layout Cycle Detected Layout could not complete" when using custom control

查看:135
本文介绍了Silverlight错误“检测到布局周期的布局无法完成​​".使用自定义控件时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过Silverlight构建一个自定义控件,方法是从ContentControl派生出来,并进行一些特殊的格式化以在内容后面放置一个阴影.

I'm building a custom control in Silverlight by deriving from ContentControl and doing some special formatting to put a dropshadow behind the contents.

我几乎可以正常工作了,但是最近遇到了一个奇怪的错误.如果它包含Border或Grid/Stackpanel/etc中没有明确定义的高度和宽度的其他内容,则它可以正常工作.

I've nearly got it working but have recently ran into a bizarre error. It works fine if it contains anything besides a Border, or a Grid/Stackpanel/etc that does not have an explicitly defined height and width.

我在IE中遇到JavaScript错误,文字显示:

I get a JavaScript error in IE, and the text says:

运行时错误4008 ...检测到布局周期...布局无法完成​​.

Runtime Error 4008... Layout Cycle Detected... Layout Could Not Complete.

如果我在所包含的网格/堆栈面板/等上指定高度和宽度,则可以正常工作.

If I specify a height and width on the contained grid/stackpanel/etc it works fine.

当使用过多的文本框(超过250个)时,网络上会出现大量有关此错误的信息,但是我可以使用网格中的单个按钮来重现我的错误.

There is a ton on the web about this error when too many textboxes are used (over 250), but I'm able to reproduce my error with a single button in a grid.

我在页面上没有任何文本框.该错误与检测到的无限循环有关.我在代码中设置了几个断点,并且似乎在渲染过程中经常调用"SizeChanged"事件,并且每次高度/宽度增加10时.

I have no textboxes at all on the page. The error has to do with a detected infinite loop. I set a few breakpoints in the code and it seems that the "SizeChanged" event is getting called a lot during rendering, and each time the height/width increments by 10.

我假设设置默认的高度/宽度会导致它跳过此数字的递增,但是我不知道为什么会发生此错误.

I'm assuming that setting a default height/width causes it to skip this incrementing of the number, but I have no idea why this error is happening.

有人遇到这个问题或有什么想法吗?

Has anyone ran into this or have any ideas?

推荐答案

有一个基本上可以发生的是,您正在某个地方更改MeasureOverride中的某个大小,该大小会导致另一种度量,从而改变大小,从而导致一种度量,依此类推.我之前碰到过这个问题,并通过删除在布局周期内导致布局更新或触发布局更新的任何代码来对其进行了修复.

Bascially what can happen is you're changing some size in a MeasureOverride somewhere which causes another measure, which changes the size, which causes a measure and so on. I ran into this once before and fixed it by removing any code that caused a layout update or triggered a layout update during the layout cycle.

更新:由于博客文章不见了,请在此处完整引用:

Update: Since the blog post is gone, quoting it here in full:

继续我关于Silverlight 2的一系列陷阱,我想谈一谈人们看到的一个常见错误.当将代码从Beta 2迁移到Release Candidate或更高版本时,您可能会看到此错误.在Beta 2中,如果布局引擎检测到周期,则不会引发任何错误;据我了解,布局只是中止了.但是使用Beta2后的位会引发错误.

Continuing my series of gotchas for Silverlight 2, I wanted to talk about a common error that people are seeing. This error is something new that you might see when moving code from Beta 2 to the Release Candidate or later. In Beta 2, if the layout engine detected a cycle, it didn't throw any errors; as I understand it, the layout was just aborted. But with post Beta2 bits, an error is thrown.

您将收到的错误将指定检测到布局周期",作为消息.此错误消息非常准确-布局引擎检测到您的布局中存在周期;或者说另一种方式,那么您的版面就会出现无限循环.

The error you'll get will specify "Layout Cycle Detected" as the message. This error message is very accurate--the layout engine detected a cycle within your layout; or another way to say it, you have an infinite loop in your layout.

导致此错误的最大原因是LayoutUpdated事件处理程序中的代码.如果您的LayoutUpdated事件处理程序采取任何措施来更改控件的布局,则将导致LayoutUpdated事件一次又一次地触发::-)

The biggest culprit that leads to this error is code within the LayoutUpdated event handler. If your LayoutUpdated event handler does anything to alter the layout of your control, then that will cause the LayoutUpdated event to fire again, and again, and again... :-)

有时候,您需要在此事件处理程序中使用更改布局的代码,所以该怎么办?

Sometimes you need to have layout altering code within this event handler though, so what is one to do?

首先,您应该考虑是否真的需要在每次调用LayoutUpdated时进行布局更改.处理Loaded事件以及Application.Current.Host.Content.Resized事件是否足够.在这两个事件之间,您将在控件加载到可视化树中时得到通知,并且在主机大小调整时会得到通知,这可能会导致您需要再次更改布局.模态对话框之类的场景应属于此类.

First, you should consider whether you really need the layout changes to occur on every call to LayoutUpdated. Would it suffice to handle the Loaded event as well as the Application.Current.Host.Content.Resized event. Between these two events, you'll get notified when the control is loaded into the visual tree, and you'll get notified any time the host is resized, which could cause you to need to change your layout again. Scenarios like modal dialogs should fall into this category.

第二,如果确实需要使用LayoutUpdated,则可能只需要在布局更改周围设置一些条件即可.例如,如果要为控件计算新的宽度和高度,则在实际设置宽度和高度之前,请检查以确保当前值与您计算出的值不同.这将允许第一个LayoutUpdated事件调整控件的大小,从而触发另一个LayoutUpdated事件,但是该事件将识别出没有工作要做,并且循环将结束.

Second, if you really do need to use LayoutUpdated, you might just need to put some conditions around your layout changes. For instance, if you are calculating a new width and height for your control, before you actually set the width and height, check to make sure the current values differ from what you calculated. This will allow the first LayoutUpdated event to resize your control, which triggers another LayoutUpdated event, but that event will recognize that there's no work to do, and the cycle will end.

在处理SizeChanged事件或对控件的布局进行任何其他覆盖时,将应用这些相同的规则.

These same rules will apply when you're handling the SizeChanged event, or if you're doing any other overrides on the layout of your control.

这篇关于Silverlight错误“检测到布局周期的布局无法完成​​".使用自定义控件时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆