Silverlightエラー“レイアウトサイクルが検出されましたレイアウトを完了できませんでした”カスタムコントロールを使用する場合
-
10-07-2019 - |
質問
ContentControlから派生し、コンテンツの背後にドロップシャドウを配置する特別な書式設定を行うことにより、Silverlightでカスタムコントロールを構築しています。
ほとんど機能しましたが、最近奇妙なエラーに遭遇しました。 Border、または明示的に定義された高さと幅を持たないGrid / Stackpanel / etc以外のものが含まれている場合は正常に動作します。
IEでJavaScriptエラーが発生し、テキストに次のように表示されます:
ランタイムエラー4008 ...レイアウトサイクルが検出されました...レイアウトを完了できませんでした。
含まれるgrid / stackpanel / etcで高さと幅を指定すると、正常に機能します。
使用しているテキストボックスの数が多すぎる(250を超える)場合、このエラーについてWebに大量の情報がありますが、グリッドの1つのボタンでエラーを再現できます。
ページにテキストボックスがまったくありません。このエラーは、検出された無限ループに関係しています。コードにいくつかのブレークポイントを設定しましたが、" SizeChanged"レンダリング中にイベントが頻繁に呼び出され、そのたびに高さ/幅が10ずつ増加します。
デフォルトの高さ/幅を設定すると、この数値の増分がスキップされると想定していますが、このエラーが発生する理由はわかりません。
これにぶつかった人やアイデアがありますか
解決
基本的に何が起こるかは、どこかで MeasureOverride
でサイズを変更して、別のメジャーを引き起こしたり、サイズを変更したり、メジャーを引き起こしたりすることです。以前にこれに一度遭遇し、レイアウト更新中にレイアウト更新を引き起こしたり、レイアウトサイクル中にレイアウト更新をトリガーしたコードを削除することで修正しました。
更新:ブログの投稿がなくなったため、ここで完全に引用してください:
Silverlight 2の一連の落とし穴を続けて、人々に見られる一般的なエラーについて話をしたいと思いました。このエラーは、ベータ2からリリース候補以降にコードを移動するときに表示される可能性がある新しいものです。 Beta 2では、レイアウトエンジンがサイクルを検出した場合、エラーをスローしませんでした。私が理解しているように、レイアウトは中止されました。ただし、ベータ2以降のビットでは、エラーがスローされます。
発生するエラーには、「レイアウトサイクルの検出」が指定されます。メッセージとして。このエラーメッセージは非常に正確です。レイアウトエンジンはレイアウト内のサイクルを検出しました。または別の言い方をすれば、レイアウトに無限ループがあります。
このエラーを引き起こす最大の原因は、LayoutUpdatedイベントハンドラー内のコードです。 LayoutUpdatedイベントハンドラーがコントロールのレイアウトを変更するために何かを行うと、LayoutUpdatedイベントが何度も何度も発生します...:-)
場合によっては、このイベントハンドラ内でレイアウトを変更するコードが必要になることがありますが、どうすればよいでしょうか
まず、LayoutUpdatedを呼び出すたびにレイアウトの変更が本当に必要かどうかを検討する必要があります。 LoadedイベントとApplication.Current.Host.Content.Resizedイベントを処理すれば十分でしょうか。これらの2つのイベントの間で、コントロールがビジュアルツリーにロードされると通知され、ホストのサイズが変更されるたびに通知されるため、レイアウトを再度変更する必要があります。モーダルダイアログなどのシナリオは、このカテゴリに分類する必要があります。
第二に、本当にLayoutUpdatedを使用する必要がある場合は、レイアウトの変更に関していくつかの条件を設定するだけでよい場合があります。たとえば、コントロールの新しい幅と高さを計算する場合、実際に幅と高さを設定する前に、現在の値が計算した値と異なることを確認してください。これにより、最初のLayoutUpdatedイベントでコントロールのサイズを変更して別のLayoutUpdatedイベントをトリガーできますが、そのイベントは実行する作業がないことを認識し、サイクルは終了します。
SizeChangedイベントを処理する場合、またはコントロールのレイアウトで他のオーバーライドを行う場合、これらの同じルールが適用されます。
他のヒント
一般的な原因は、 SizeChanged
を処理してから、ハンドラーで要素のサイズに影響を与えることです。これは明らかではない場合があります。たとえば、コンテナのサイズに影響する子要素を変更している可能性があります。
1。ScrollViewer内でLongListSelectorを使用している場合は、それを削除する方が適切です。私は同じ問題に直面していて、私のLongListSelectorはScrollViewerの中にありました。 ItemRealizedイベント中に、このエラーが発生していました。
2.itemrealized内でupdatelayout()を使用しないでください。私は次のようなものを使用していました
list.UpdateLayout();
list.ScrollTo(e.Container.Content);
単にScrollToを使用する
3.longlistselector内で画像を使用している場合は、必ず画像の高さと幅を設定してください。
同じ問題が発生し、すべてのレイアウトの更新(サイズ変更)を" invoke"に入れました後で呼び出されたデリゲートenはクラッシュを停止しますが、ループ内でスタックしている良い変更があります
同じ問題が発生しましたが、非常にまれにしか発生しませんでした。私のコードは何年も変更されておらず、最近になって誰かがそれを経験することができました。
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" >