14

我正在通过从 ContentControl 派生并执行一些特殊格式以在内容后面放置阴影来在 Silverlight 中构建自定义控件。

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

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

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

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

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

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

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

有没有人遇到过这个或有任何想法?

4

5 回答 5

7

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

基本上可能发生的事情是你在MeasureOverride某个地方改变了一些尺寸,这会导致另一个测量,这会改变尺寸,这会导致测量等等。我之前遇到过一次并通过删除任何导致布局更新或在布局周期中触发布局更新的代码来修复它。

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

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

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

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

有时您需要在此事件处理程序中使用布局更改代码,那么该怎么做呢?

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

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

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

于 2009-03-12T01:23:28.473 回答
6

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

于 2009-03-12T01:30:28.113 回答
4

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

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

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

只需使用 ScrollTo

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

于 2014-03-06T09:36:20.390 回答
1

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

于 2011-05-17T12:18:52.087 回答
0

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

我在 LongListSelector DataSource 中有一个 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" >
于 2015-05-12T19:59:39.500 回答