2009-03-11 14 views
13

Buduję niestandardową kontrolkę w Silverlight, wywodzącą się z ContentControl i wykonuję specjalne formatowanie, aby umieścić cień za zawartością.Błąd Silverlight "Layout Cycle Detected Layout nie mógł się zakończyć" podczas używania formantu niestandardowego

Prawie udało mi się, że działa, ale ostatnio wpadł w dziwny błąd. Działa dobrze, jeśli zawiera coś poza obramowaniem lub Grid/Stackpanel/etc, które nie mają wyraźnie określonej wysokości i szerokości.

otrzymuję błąd JavaScript w IE, a tekst mówi:

... Runtime Error 4008 Cykl Układ Wykryto ... Układ nie może Complete.

Jeśli określę wysokość i szerokość na zawartej siatce/sterówce/itp., To działa dobrze.

W sieci jest mnóstwo informacji o tym błędzie, gdy użyto zbyt wielu pól tekstowych (ponad 250), ale jestem w stanie odtworzyć błąd za pomocą jednego przycisku w siatce.

Nie mam żadnych pól tekstowych na stronie. Błąd związany jest z wykrytą nieskończoną pętlą. Ustawiłem kilka punktów przerwania w kodzie i wydaje się, że zdarzenie "SizeChanged" jest wywoływane podczas renderowania, a za każdym razem wysokość/szerokość zwiększa się o 10.

Zakładam, że ustawienie domyślnej wysokości/width powoduje, że pomijane jest zwiększanie liczby, ale nie mam pojęcia, dlaczego tak się dzieje.

Czy ktoś wpadł na to lub miał jakieś pomysły?

+0

Zabrakło mi do tego problemu z kontrolą Telerik RadWindow (to pewnie też zdarzyć, ze zwykłej ChildWindow). Problem wystąpił, gdy określono MinHeight i MinWidth bez określania szerokości i wysokości. Gdy zmienił się rozmiar zawartości okna, wystąpił cykl układu. Ustawienie szerokości i wysokości na takie same wartości jak MinWidth i MinHeight rozwiązało problem. –

Odpowiedz

7

Istnieje good blog post on this error here.

W gruncie rzeczy może się zdarzyć, że zmienisz jakiś rozmiar w rozmiarze MeasureOverride, co powoduje kolejną miarę, która zmienia rozmiar, co powoduje pomiar i tak dalej. Wpadłem na to wcześniej i naprawiłem go, usuwając kod, który spowodował aktualizację układu lub wywołał aktualizację układu podczas cyklu układania.

Aktualizacja: Ponieważ blogu nie ma, powołując go tutaj w całości:

Kontynuując moją serię pułapek dla Silverlight 2, chciałem mówić o wspólnym błędem, że ludzie widząc. Ten błąd jest czymś nowym, co możesz zobaczyć po przeniesieniu kodu z wersji Beta 2 do wersji Release Candidate lub nowszej. W wersji Beta 2, jeśli silnik układu wykrył cykl, nie wygenerował żadnych błędów; jak rozumiem, układ został po prostu przerwany. Ale z bitami po Beta2, zgłoszony zostanie błąd.

Otrzymany błąd określi jako "Komunikat o wykrytym cyklu układu". Ten komunikat o błędzie jest bardzo dokładny - silnik układu wykrył cykl w twoim układzie; lub inny sposób, aby to powiedzieć, masz nieskończoną pętlę w swoim układzie.

Największym winowajcą, który doprowadził do tego błędu, jest kod w ramach obsługi zdarzeń LayoutUpdated. Jeśli funkcja obsługi zdarzeń LayoutUpdated zrobi wszystko, aby zmienić układ kontrolki, spowoduje to ponowne uruchomienie zdarzenia LayoutUpdated, i znowu i znowu ... :-)

Czasami potrzebny jest kod zmiany układu w obrębie ten program obsługi zdarzeń, więc co zrobić?

Po pierwsze, należy rozważyć, czy naprawdę potrzebne są zmiany układu przy każdym wywołaniu funkcji LayoutUpdated. Czy wystarczy obsłużyć zdarzenie Loaded, jak również zdarzenie Application.Current.Host.Content.Resized. Pomiędzy tymi dwoma zdarzeniami otrzymasz powiadomienie, gdy kontrola zostanie załadowana do drzewa wizualnego, a otrzymasz powiadomienie o każdej zmianie rozmiaru hosta, co może spowodować konieczność ponownego zmiany układu. Scenariusze takie jak dialogi modalne powinny należeć do tej kategorii.

Po drugie, jeśli naprawdę potrzebujesz użyć narzędzia LayoutUpdated, możesz po prostu wprowadzić pewne warunki wokół zmian w układzie. Na przykład, jeśli obliczasz nową szerokość i wysokość dla kontroli, zanim faktycznie ustawisz szerokość i wysokość, sprawdź, czy bieżące wartości różnią się od obliczonych. Dzięki temu pierwsze zdarzenie LayoutUpdated zmieni rozmiar kontrolki, co wyzwoli kolejne zdarzenie LayoutUpdated, ale zdarzenie to rozpozna, że ​​nie ma żadnej pracy, a cykl się zakończy.

Te same zasady obowiązują podczas obsługi zdarzenia SizeChanged lub w przypadku innych nadpisań w układzie kontrolki.

+0

To jest problem, który widzę. Połączony post na blogu sugeruje, że robisz tylko rzeczy na pierwszym załadowaniu, a aplikacja silverlight (kontrolka użytkownika) zmienia swój rozmiar.To może dla mnie zadziałać, ale nie testowałem go jeszcze podczas animacji i innych działań. Dzięki za pomoc! –

+0

@bryant blog dead; ( – MemeDeveloper

+0

Wayback maszyna na ratunek: https://web.archive.org/web/20110203182929/http://jeffhandley.com/archive/2008/09/26/silverlight-2-post- beta2-gotcha --- layout-cycle-detected.aspx – Bryant

6

Powszechną przyczyną jest obsługa SizeChanged, a następnie w programie obsługi robi się coś, co wpływa na rozmiar elementu. Czasem nie jest to oczywiste - może to być modyfikowanie elementów podrzędnych, które na przykład wpływają na wielkość ich kontenera.

1

miałem ten sam problem i co zrobiłem było umieścić wszystkie aktualizacje układu (zmiany rozmiaru) w „powołać” pełnomocnika pl wywołana później, zatrzymuje upaść, ale istnieje duża zmiana to utknął w pętli

4

1.Jeśli używasz LongListSelector w ScrollViewer, lepiej go usuń. Wystąpił ten sam problem i mój program LongListSelector był w ScrollViewer. Podczas zdarzenia ItemRealized wystąpił błąd.

2.Don't używać updatelayout() wewnątrz itemrealized..I używał coś

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

Wystarczy użyć scrollTo

3.Jeżeli używasz obrazu wewnątrz longlistselector, upewnij się, aby ustawić wysokość i szerokość obrazu.

0

Miałem ten sam problem, ale zdarzało się to wyjątkowo rzadko, mój kod nie zmieniał się od lat i dopiero niedawno ktoś go doświadczył.

miałem TextBlock wewnątrz DataSource LongListSelector i jego FontSize był ustawiony na 21. Zmiana fontSize do jakiejkolwiek innej wartości stałej problem dla mnie ...

moich LongListSelectors jest wewnątrz 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" >