2013-05-01 114 views
8

我在看this question,發現一些非常奇怪的事情:在一些涉及Grid.RowSpan的案例中,似乎錯誤地計算了一行的高度。爲什麼這個額外的空間出現在網格中?

這裏的Grid的簡單的畫圖我與測試:

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

,這裏是這個網格一些示例代碼演示該問題:

<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> 

最終的結果是高度第3行(單元#2和#3)有很多額外的空間:

enter image description here

如果我將第一個和第三個單元格的Grid.RowSpan調整爲+/- 1,並將第二個和第四個單元格的Grid.Row調整爲+/- 1以考慮多餘的行,我得到以下(正確)結果:

enter image description here

我也得到正確的結果,如果我從小區#3去除足夠的元素,因此它可以在一個單一的行渲染,就像這樣:

enter image description here

而且奇怪的是,刪除一些對象只導致s額外空間的OME應用於

enter image description here

我一直在細胞中的元素#1和#3,和行數的數量瞎搞,但我似乎無法找出一個確鑿的模式來解釋這種行爲。

究竟是什麼WPF在幕後進行渲染這個Grid時導致額外的空間出現在單元格3上的Grid.RowSpan

+0

我想說,因爲網格的措施不同,但我嘗試了所有的堆疊面板,它仍然大小錯誤的行。 – Paparazzi 2013-05-01 17:41:14

+0

有太多'自動'排高度。 Grid控件在處理行和列跨越方面做得非常好,但是當所有行高設置爲「Auto」時,就像解決一個有太多未知數的方程一樣。將頂端2行中的1個或兩個固定在一個固定的高度會極大地幫助您。 – Stewbob 2013-05-01 19:27:59

+0

@Stewbob我也在'Height =「*」'上留下最後一行進行了測試,並沒有什麼區別。問題在於確定使用「RowSpan」的單元格的高度,而與「Grid」如何分配額外的垂直空間無關。我已更新我的代碼示例以包含一個'*'大小的行以幫助將其清除:) – Rachel 2013-05-01 20:04:24

回答

0

我沒有一個完整的答案,爲什麼.NET做你的第三行錯了。
但我爭辯說,你要求它做的是不合邏輯的,因爲沒有理由讓0,0跨越兩行。
當共享行時,它們的長度不可能相等,WPF必須將長度加到較短的(s)。
由於您在共享行中共享行,因此WPF必須應用一些權重並且不會正確執行此操作。
如果你沒有跨越0 0,那麼就等於對第0行第0列和第1行第0列共享額外的額外空間,這對我來說是正確的答案。

<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

是的,我知道這樣的代碼是不合邏輯的,並且有避免這種行爲的簡單方法,例如刪除不需要的和未定義的第二行(Grid.Row =「1」),但我很好奇WPF在後臺執行什麼操作首先決定渲染這種方式,並且只使用特定的RowSpans。我懷疑你是對的,WPF在測量未定義的行時應用了一些不正確的權重,因爲元素的數量影響了多少額外空間。我猜我需要拉出反射器才能得到一個明確的答案... – Rachel 2013-05-02 16:30:59

+1

我懷疑它得到的權重是錯誤的(但沒有正確的理由,我可以看到使它的重量)。如果你看到什麼看起來是正確的加權,我懷疑增量爲0,加權0錯誤,你沒有看到錯誤的答案。 – Paparazzi 2013-05-02 16:36:55

1

我在my question here碰到這種情況之前,大約額外的空間appearing in a ListView

每筆者從微軟的員工得到了響應:

該缺陷涉及的步驟在VSP的Measure算法中,它記住了以前發現的最大尺寸,並且強制所有未來的Measure調用報告至少一樣大的尺寸。在你的情況下,VSP是在任何觸發器開始觸發之前進行初始測量的,所以它計算出所有事件都可見的大小。當觸發器觸發並摺疊按鈕時,度量算法會計算正確的(小)尺寸,但會強制再次調整結果。

網格的行爲出現類似於我的虛擬化堆棧面板的行爲:有些事情正在發生與RowDefinition的措施調用,迫使它記住並始終報告尺寸較大,即使後來就停機這條線越小越好。

簡而言之,您可能在WPF中發現了一個錯誤,因爲有無數的解決方法(匹配總共需要的行數,重新排列您的網格,其他任何...)可能永遠不會受到關注。您只能通過打開Microsoft Connect錯誤並等待他們的回覆來確認或駁回此問題。

+2

你鏈接的帖子非常有趣,我懷疑你是正確的,它是度量調用中的一個錯誤。我希望你不介意,但我會編輯你的答案一點,以包括你的鏈接帖子的相關報價。我希望有人會發佈一個答案,解釋幕後發生的情況,並通過反射器或MSDN代碼進行備份,但看起來不會發生這種情況,所以我會按照我的想法授予您賞金代表你的答案是最接近我會得到一個堅實的答案。 – Rachel 2013-05-14 16:09:31

+0

Rachel我認爲你只是展示了一個好編輯的價值。蘭登書屋,注意! – 2013-05-14 17:14:35

0

正如Rob所說,這可能是WPF測量呼叫時的一個錯誤。所以我不知道你的答案。但爲了探索WPF應用程序的內部運作,我使用Snoop。這是一個非常棒的工具,類似於顯示HTML元素的瀏覽器工具,snoop向您展示了您的WPF表單佈局,嵌套元素,元素屬性等等。當試圖找出佈局問題時,它幫助我很多。我想我會提到。

相關問題