14

ContentControl から派生させ、特別な書式設定を行ってコンテンツの背後にドロップ シャドウを配置することにより、Silverlight でカスタム コントロールを構築しています。

ほぼ動作するようになりましたが、最近奇妙なエラーに遭遇しました。Border 以外のものが含まれている場合、または明示的に定義された高さと幅を持たない Grid/Stackpanel/etc が含まれている場合は、正常に機能します。

IE で JavaScript エラーが発生し、テキストには次のように表示されます。

ランタイム エラー 4008... レイアウト サイクルが検出されました... レイアウトを完了できませんでした。

含まれているグリッド/スタックパネル/などで高さと幅を指定すると、正常に機能します。

あまりにも多くのテキストボックスが使用されている場合 (250 以上)、このエラーについてウェブ上にたくさんありますが、グリッド内の 1 つのボタンでエラーを再現できます。

ページにテキストボックスがまったくありません。このエラーは、検出された無限ループに関係しています。コードにいくつかのブレークポイントを設定しましたが、レンダリング中に「SizeChanged」イベントが頻繁に呼び出され、高さ/幅が 10 ずつ増加するようです。

デフォルトの高さ/幅を設定すると、この数値の増分がスキップされると想定していますが、このエラーが発生する理由はわかりません。

誰かがこれに遭遇したか、何かアイデアがありますか?

4

5 に答える 5

7

このエラーに関する適切なブログ投稿がここにあります。

基本的に起こりうることは、MeasureOverrideどこかでサイズを変更すると、別のメジャーが発生し、サイズが変更され、メジャーが発生するなどです。以前にこれに遭遇し、レイアウトの更新を引き起こしたコード、またはレイアウト サイクル中にレイアウトの更新をトリガーしたコードを削除して修正しました。

更新: ブログ投稿がなくなったので、ここに全文を引用します。

Silverlight 2 に関する一連の落とし穴の続きとして、よく見られるエラーについてお話ししたいと思います。このエラーは、コードを Beta 2 から Release Candidate 以降に移動するときに表示される可能性がある新しいものです。Beta 2 では、レイアウト エンジンがサイクルを検出した場合、エラーは発生しませんでした。私が理解しているように、レイアウトは中止されました。しかし、ベータ 2 後のビットでは、エラーがスローされます。

表示されるエラーは、メッセージとして「Layout Cycle Detected」を指定します。このエラー メッセージは非常に正確です。レイアウト エンジンがレイアウト内のサイクルを検出しました。別の言い方をすれば、レイアウトに無限ループがあります。

このエラーを引き起こす最大の原因は、LayoutUpdated イベント ハンドラー内のコードです。LayoutUpdated イベント ハンドラーがコントロールのレイアウトを変更するために何かを行うと、LayoutUpdated イベントが何度も何度も発生します... :-)

ただし、このイベント ハンドラー内でコードを変更するレイアウトが必要になる場合があります。

まず、LayoutUpdated を呼び出すたびにレイアウトを変更する必要があるかどうかを検討する必要があります。Loaded イベントと Application.Current.Host.Content.Resized イベントを処理するだけで十分でしょうか。これら 2 つのイベントの間に、コントロールがビジュアル ツリーに読み込まれたときに通知を受け取り、ホストのサイズが変更されるたびに通知を受け取ります。これにより、レイアウトを再度変更する必要が生じる可能性があります。モーダル ダイアログのようなシナリオは、このカテゴリに分類されます。

次に、本当に LayoutUpdated を使用する必要がある場合は、レイアウトの変更に関していくつかの条件を設定するだけでよい場合があります。たとえば、コントロールの新しい幅と高さを計算する場合、幅と高さを実際に設定する前に、現在の値が計算した値と異なることを確認してください。これにより、最初の LayoutUpdated イベントによってコントロールのサイズが変更され、別の LayoutUpdated イベントがトリガーされますが、そのイベントは実行する作業がないことを認識し、サイクルが終了します。

SizeChanged イベントを処理している場合、またはコントロールのレイアウトで他のオーバーライドを行っている場合は、これらと同じ規則が適用されます。

于 2009-03-12T01:23:28.473 に答える
6

一般的な原因はSizeChanged、要素のサイズに影響を与える何かを処理し、ハンドラーで実行することです。これは明らかでない場合もあります。たとえば、コンテナのサイズに影響を与える子要素を変更している可能性があります。

于 2009-03-12T01:30:28.113 に答える
1

私は同じ問題を抱えていました。私がしたことは、すべてのレイアウトの更新 (サイズの変更) を後で呼び出された "invoke" デリゲートに入れることでした。

于 2011-05-17T12:18:52.087 に答える