Silverlight 错误“布局周期检测到的布局无法完成​​” 当使用自定义控件时

发布于 2024-07-15 02:22:01 字数 574 浏览 3 评论 0原文

我正在 Silverlight 中构建一个自定义控件,方法是从 ContentControl 派生并执行一些特殊的格式设置以在内容后面放置阴影。

我几乎已经让它工作了,但最近遇到了一个奇怪的错误。 如果它包含除边框或网格/堆栈面板/等之外没有明确定义的高度和宽度的任何内容,它就可以正常工作。

我在 IE 中收到 JavaScript 错误,文本显示:

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

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

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

我的页面上根本没有文本框。 该错误与检测到的无限循环有关。 我在代码中设置了一些断点,似乎在渲染过程中多次调用“SizeChanged”事件,并且每次高度/宽度都会增加 10。

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

有没有人遇到过这个或有什么想法?

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

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.

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

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.

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

若言繁花未落 2024-07-22 02:22:01

有一个 关于此错误的好博文在这里

基本上可能发生的情况是,您在某个地方更改了 MeasureOverride 中的某些大小,这会导致另一个测量,该测量会更改大小,从而导致另一个测量,依此类推。 我之前遇到过这个问题,并通过删除导致布局更新或在布局周期期间触发布局更新的任何代码来修复它。

更新:由于博客文章已消失,因此在此全文引用:

继续我的 Silverlight 2 陷阱系列,我想谈谈人们看到的一个常见错误。 此错误是您在将代码从 Beta 2 移动到候选版本或更高版本时可能会看到的新错误。 在 Beta 2 中,如果布局引擎检测到循环,它不会抛出任何错误; 据我了解,布局刚刚中止。 但对于 Beta2 后的位,会引发错误。

您收到的错误将指定“检测到布局周期”作为消息。 此错误消息非常准确 - 布局引擎在布局中检测到循环; 或者换句话说,您的布局中有一个无限循环。

导致此错误的最大罪魁祸首是 LayoutUpdated 事件处理程序中的代码。 如果您的 LayoutUpdated 事件处理程序执行任何操作来更改控件的布局,那么这将导致 LayoutUpdated 事件一次又一次地触发...:-)

有时您需要在此事件处理程序中包含布局更改代码,那么该怎么办?

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

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

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

There is a good blog post on this error here.

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:

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.

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?

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.

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.

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.

窝囊感情。 2024-07-22 02:22:01

一个常见的原因是处理 SizeChanged,然后在处理程序中执行一些影响元素大小的操作。 有时这并不明显 - 例如,它可能会修改影响其容器大小的子元素。

A common cause is handling SizeChanged and then in the handler doing something that affects the size of the element. Sometimes this is not obvious - it could be modifying child elements which affect the size of their container for instance.

舟遥客 2024-07-22 02:22:01

1.如果您在ScrollViewer中使用LongListSelector,最好将其删除。 我面临同样的问题,我的 LongListSelector 位于 ScrollViewer 内。 在 ItemRealized 事件期间,收到此错误。

2.不要在 itemrealized 中使用 updatelayout() ..我使用的是类似

 list.UpdateLayout();
 list.ScrollTo(e.Container.Content);

Simple use ScrollTo

3.如果您在 longlistselector 中使用图像,请确保设置图像的高度和宽度。

1.If you are using LongListSelector inside ScrollViewer, better remove that. I was facing the same problem and my LongListSelector was inside ScrollViewer. During ItemRealized event, was getting this error.

2.Don't use updatelayout() inside itemrealized..I was using something like

 list.UpdateLayout();
 list.ScrollTo(e.Container.Content);

Simply use ScrollTo

3.If you are using image inside longlistselector, make sure to set the height and width of the image.

野の 2024-07-22 02:22:01

我遇到了同样的问题,我所做的是将所有布局更新(大小更改)放入稍后调用的“调用”委托中,它停止崩溃,但你有一个很好的更改,它陷入了循环

I had the same problem and what i did was put all the layout updates (size changes) in a "invoke" delegate en invoked later, it stops crashing but you there is a good change it's stuck in a loop

心碎无痕… 2024-07-22 02:22:01

我遇到了同样的问题,但这种情况很少发生,我的代码多年来没有改变,直到最近才有人设法经历它。

我在 LongListSelector 数据源内有一个 TextBlock,其 FontSize 设置为 21。将 FontSize 更改为任何其他值解决了我的问题...

我的 LongListSelectors 在 ScrollViewer 内。

            <phone:PanoramaItem x:Name="OwnedGamesPanoramaItem" >
            <ScrollViewer Margin="5,-25,0,0">
            <StackPanel>
                    <TextBlock toolkit:TiltEffect.IsTiltEnabled="True" Text="{Binding Path=LocalizedResources.XOwnedGames, Source={StaticResource LocalizedStrings}}" FontFamily="Segoe WP Semibold" CharacterSpacing="10"  FontSize="25" Margin="0,10,0,25" TextWrapping="Wrap"/>
                    <TextBlock x:Name="ownedGameLoadingTextBox" Margin="10" FontSize="26" Text="{Binding Path=LocalizedResources.XLoading, Source={StaticResource LocalizedStrings}}" HorizontalAlignment="Center"/>
                    <phone:LongListSelector x:Name="OwnedGameListBox" Tap="OwnedGameListBoxTap" ScrollViewer.VerticalScrollBarVisibility="Disabled" ItemRealized="OwnedGameListBox_ItemRealized" ItemUnrealized="OwnedGameListBox_ItemUnrealized" BorderThickness="0,20,0,0"  >
                        <phone:LongListSelector.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical" Tap="OwnedGameListBoxTap" Margin="0,0,0,12">
                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" Tap="StackPanel_Tap_1">
                                        <Image Width="60" Source="{Binding getSmallImageActualURL}" Height="60"  Margin="3" VerticalAlignment="Top" />
                                        <StackPanel Margin="15,0,0,0">
                                            <TextBlock Width="320" TextWrapping="Wrap" Text="{Binding name}" Margin="0,0,0,0" FontSize="32" />
                                            <TextBlock Text="{Binding getTotalPlaytimeFormatted}" Margin="0,0,0,0" TextWrapping="Wrap" FontSize="21" >
                                                <TextBlock.Foreground>
                                                    <SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
                                                </TextBlock.Foreground>
                                            </TextBlock>
                                        </StackPanel>
                                    </StackPanel>
                                </StackPanel>
                            </DataTemplate>
                        </phone:LongListSelector.ItemTemplate>
                    </phone:LongListSelector>
                </StackPanel>
            </ScrollViewer>
        </phone:PanoramaItem>

使固定:

<TextBlock Text="{Binding getTotalPlaytimeFormatted}" Margin="0,0,0,0" TextWrapping="Wrap" FontSize="22" >

I had the same problem but it only occurred extremely rarely, my code hasn't changed for years and only recently someone managed to experience it.

I had a TextBlock inside a LongListSelector DataSource and its FontSize was set to 21. Changing the FontSize to ANY other value fixed the problem for me...

My LongListSelectors is inside a ScrollViewer.

            <phone:PanoramaItem x:Name="OwnedGamesPanoramaItem" >
            <ScrollViewer Margin="5,-25,0,0">
            <StackPanel>
                    <TextBlock toolkit:TiltEffect.IsTiltEnabled="True" Text="{Binding Path=LocalizedResources.XOwnedGames, Source={StaticResource LocalizedStrings}}" FontFamily="Segoe WP Semibold" CharacterSpacing="10"  FontSize="25" Margin="0,10,0,25" TextWrapping="Wrap"/>
                    <TextBlock x:Name="ownedGameLoadingTextBox" Margin="10" FontSize="26" Text="{Binding Path=LocalizedResources.XLoading, Source={StaticResource LocalizedStrings}}" HorizontalAlignment="Center"/>
                    <phone:LongListSelector x:Name="OwnedGameListBox" Tap="OwnedGameListBoxTap" ScrollViewer.VerticalScrollBarVisibility="Disabled" ItemRealized="OwnedGameListBox_ItemRealized" ItemUnrealized="OwnedGameListBox_ItemUnrealized" BorderThickness="0,20,0,0"  >
                        <phone:LongListSelector.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical" Tap="OwnedGameListBoxTap" Margin="0,0,0,12">
                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,10,0,0" Tap="StackPanel_Tap_1">
                                        <Image Width="60" Source="{Binding getSmallImageActualURL}" Height="60"  Margin="3" VerticalAlignment="Top" />
                                        <StackPanel Margin="15,0,0,0">
                                            <TextBlock Width="320" TextWrapping="Wrap" Text="{Binding name}" Margin="0,0,0,0" FontSize="32" />
                                            <TextBlock Text="{Binding getTotalPlaytimeFormatted}" Margin="0,0,0,0" TextWrapping="Wrap" FontSize="21" >
                                                <TextBlock.Foreground>
                                                    <SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
                                                </TextBlock.Foreground>
                                            </TextBlock>
                                        </StackPanel>
                                    </StackPanel>
                                </StackPanel>
                            </DataTemplate>
                        </phone:LongListSelector.ItemTemplate>
                    </phone:LongListSelector>
                </StackPanel>
            </ScrollViewer>
        </phone:PanoramaItem>

Fix:

<TextBlock Text="{Binding getTotalPlaytimeFormatted}" Margin="0,0,0,0" TextWrapping="Wrap" FontSize="22" >
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文