2013-05-01 12 views
8

Patrzyłem na this question i odkryłem coś bardzo dziwnego: wydaje się, że wysokość rzędu jest niepoprawnie obliczona w niektórych przypadkach z udziałem Grid.RowSpan.Dlaczego ta dodatkowa przestrzeń pojawia się w siatce?

Oto prosty rysunek Grid mam testowanie z:

 
--------------- 
| 1 |  | 
--------| 3 | 
| 2 |  | 
--------------- 
|  4  | 
--------------- 

A oto przykładowy kod dla tej siatki, który demonstruje problem:

<Grid ShowGridLines="True"> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 

    <StackPanel Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Background="Red"> 
     <Label Content="CELL 1 A"/> 
     <Label Content="CELL 1 B"/> 
     <Label Content="CELL 1 C"/> 
    </StackPanel> 

    <Grid Grid.Column="0" Grid.Row="2" Background="CornflowerBlue"> 
     <Label Content="CELL 2 D"/> 
    </Grid> 

    <StackPanel Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Background="Yellow"> 
     <Label Content="CELL 3 A"/> 
     <Label Content="CELL 3 B"/> 
     <Label Content="CELL 3 C"/> 
     <Label Content="CELL 3 D"/> 
    </StackPanel> 


    <Grid Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Background="Green"> 
     <Label Content="CELL 4"/> 
    </Grid> 
</Grid> 

Końcowym rezultatem jest wysokość w trzecim wierszu (komórka nr 2 i nr 3) ma dużo dodatkowej przestrzeni:

enter image description here

Jeśli ustawię Grid.RowSpan z 1. i 3. komórki przez +/- 1 i dostosuję Grid.Row dla 2. i 4. pozycji przez +/- 1, aby uwzględnić dodatkowy wiersz, otrzymam ten (prawidłowy) wynik:

enter image description here

ja również uzyskać poprawne wyniki jeśli usunąć wystarczająco dużo elementów z komórki # 3 więc może to uczynić w jednym rzędzie, tak:

enter image description here

i na tyle dziwnie, usuwanie jednych obiekty dają tylko s ome z dodatkowej przestrzeni stosowane

enter image description here

Byłem pałować z liczbą elementów w komórkach # 1 i # 3, a liczba wierszy, ale nie wydaje się, aby dowiedzieć się rozstrzygający wzór wyjaśniający to zachowanie.

Czym dokładnie jest WPF za sceną podczas renderowania tej siatki w celu spowodowania pojawienia się dodatkowego miejsca w komórce nr 3 podczas Grid.RowSpan?

+0

Miałem zamiar powiedzieć, ponieważ kratka mierzy inaczej, ale wypróbowałem ją ze wszystkimi panelami piętrowymi i nadal rozmiar ten jest nieprawidłowy. – Paparazzi

+0

Zbyt wiele rzędów "Auto". Kontrolka Grid radzi sobie całkiem nieźle z rozpiętością rzędów i kolumn, ale kiedy wszystkie poziomy rzędów są ustawione na "Auto", to jak rozwiązywanie równania ze zbyt wieloma niewiadomymi. Ograniczenie 1 lub obu górnych 2 rzędów do ustalonej wysokości pomaga niezmiernie. – Stewbob

+0

@Stewbob Testowałem również, pozostawiając ostatni wiersz w 'Height =" * "' i nie ma to znaczenia. Problem polega na określeniu wysokości komórki, która używa 'RowSpan' i nie jest związana z tym, w jaki sposób' Grid' przydziela dodatkową pionową przestrzeń. Zaktualizowałem próbkę kodu tak, aby zawierał wiersz o rozmiarze "*", aby to wyjaśnić :) – Rachel

Odpowiedz

0

Nie mam pełnej odpowiedzi na pytanie, dlaczego .NET robi zły 3 wiersz.
Ale twierdzę, że to, o co prosisz, jest nielogiczne, ponieważ nie ma powodu, aby mieć 0,0 rozpiętości dwóch rzędów.
Gdy wiersze są udostępniane, prawdopodobnie nie mają równej długości, a WPF musi dodać długość do krótszego (s).
W tobie, ponieważ masz wspólne wiersze we współdzielonych wierszach, więc WPF musi zastosować pewne ważenie i nie robi tego poprawnie.
Jeśli nie rozciągasz się na 0 0, to dzieli się dodatkową przestrzenią z kolumną 0 kolumna 0 i kolumną 1 kolumna 0 jednakowo, która (dla mnie) jest poprawną odpowiedzią.

<Window x:Class="GridRowSizing.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <Style BasedOn="{StaticResource {x:Type Label}}" TargetType="Label"> 
      <Setter Property="BorderBrush" Value="Black"/> 
      <Setter Property="BorderThickness" Value="1"/> 
      <Setter Property="Margin" Value="3"/> 
     </Style> 
    </Window.Resources> 
    <Grid ShowGridLines="True"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <StackPanel Grid.Column="0" Grid.Row="0" Background="Red"> 
      <Label Content="CELL 1 A"/> 
      <Label Content="CELL 1 B"/> 
      <Label Content="CELL 1 C" BorderBrush="Black" BorderThickness="2"/> 
     </StackPanel> 
     <StackPanel Grid.Column="0" Grid.Row="1" Background="CornflowerBlue"> 
      <Label Content="CELL 2 D" BorderBrush="Black" BorderThickness="2"/> 
      <Label Content="CELL 2 E" BorderBrush="Black" BorderThickness="2"/> 
     </StackPanel> 
     <StackPanel Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Background="Yellow"> 
      <Label Content="CELL 3 A"/> 
      <Label Content="CELL 3 B"/> 
      <Label Content="CELL 3 C"/> 
      <Label Content="CELL 3 D" BorderBrush="Black" BorderThickness="2"/> 
      <Label Content="CELL 3 E" BorderBrush="Black" BorderThickness="2"/> 
      <Label Content="CELL 3 F" BorderBrush="Black" BorderThickness="2"/> 
     </StackPanel> 
     <StackPanel Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Background="Green"> 
      <Label Content="CELL 4"/> 
     </StackPanel> 
    </Grid> 
</Window> 
+0

Tak, wiem, że taki kod jest nielogiczny i że istnieją proste sposoby na uniknięcie takiego zachowania, na przykład usunięcie niepotrzebnego i niezdefiniowanego drugiego wiersza (Grid.Row = "1"), ale byłem ciekawy, co WPF robi za kulisami zdecyduj się renderować w ten sposób w pierwszej kolejności i tylko w określonych RowSpans. Podejrzewam, że masz rację, że WPF stosuje niewłaściwe ważenie, mierząc niezdefiniowany wiersz, ponieważ liczba elementów wpływa na ilość dodatkowego miejsca. Zgaduję, że będę musiał wyjąć reflektor, aby uzyskać definitywną odpowiedź na ten temat ... – Rachel

+1

Podejrzewam, że otrzymuję wagę złą (ale nie ma ważnego powodu, dla którego mogę zobaczyć, aby ją obciążyć). Gdzie widzisz, co wydaje się być prawidłowym ważeniem, podejrzewam, że delta wynosi 0, a ważąc 0, nie widzisz złą odpowiedź. – Paparazzi

1

Zabrakło mi na tego rodzaju stan przed, jak w my question here o dodatkową przestrzeń appearing in a ListView

Per odpowiedź dostałem od pracownika firmy Microsoft:

Bug obejmuje etap w algorytmie VSP Measure, który zapamiętuje największy odkryty rozmiar i wymusza wszystkie przyszłe wywołania Measure, aby zgłosić rozmiar co najmniej tak duży. W twoim przypadku VSP jest początkowo mierzony przed uruchomieniem jakichkolwiek wyzwalaczy, więc oblicza rozmiar tak, jakby wszystko było widoczne.Kiedy wyzwalacze odpalają i zwiną przyciski, algorytm pomiaru wylicza prawidłowy (mały) rozmiar, ale następnie zmusza wynik do ponownego zwiększenia.

Zachowanie swojej sieci pojawia się podobny do zachowania mojego wirtualizacji paneli: Coś się dzieje z RowDefinition „s połączeń środków, które zmuszają go do zapamiętania i zawsze zgłosić większy rozmiar, chociaż później na dół linia, mniejsza, byłaby lepsza.

Krótko mówiąc, prawdopodobnie znalazłeś błąd w WPF, który, ponieważ istnieje mnóstwo błędów (dopasuj sumy wierszy zdefiniowanych do sumy potrzebnej, zmień kolejność siatki, cokolwiek innego ...) może nigdy nie zyskać uwagi. Możesz potwierdzić lub odrzucić to tylko przez otwarcie błędu Microsoft Connect i czekanie na odpowiedź.

+2

Ten wpis, który połączyłeś, był bardzo interesujący i podejrzewam, że masz rację, ponieważ jest błędem w wywołaniach Zmierz. Mam nadzieję, że nie masz nic przeciwko temu, ale zamierzam trochę zmodyfikować twoją odpowiedź, by uwzględnić względny cytat z połączonego wpisu. Miałem nadzieję, że ktoś opublikuje odpowiedź wyjaśniającą dokładnie, co dzieje się za kulisami, aby to się stało, wsparte przez reflektor lub kod MSDN, ale nie wygląda na to, że tak się stanie, więc przyznam ci nagrodę, tak jak myślę. twoja odpowiedź jest najbliższą rzeczą, którą dostanę do solidnej odpowiedzi. – Rachel

+0

Rachel Myślę, że właśnie zademonstrowałeś wartość dobrego redaktora. Losowy dom, zanotuj! –

0

Jak powiedział Rob, jest to prawdopodobnie błąd w wywołaniach pomiarowych WPF. Więc nie znam twojej odpowiedzi. Ale aby zbadać wewnętrzne działanie aplikacji WPF, używam Snoop. To niesamowite narzędzie, podobne do narzędzi przeglądarki, które pokazują elementy HTML, snoop pokazuje, jak układa się formularz WPF, elementy zagnieżdżone, właściwości elementów itp. Bardzo pomaga mi to przy rozwiązywaniu problemów z układem. Myślałem, że wspomnę.

Powiązane problemy