2010-10-08 61 views
4

對於包含以特定方式指定的元素的兩個網格和SharedSizeGroup,似乎存在一些問題。使用SharedSizeGroup測量/排列網格

這個問題是在迴應earlier questionuser D.H.我試圖回答。原諒的長度,但它有助於直觀地展示問題。

他的原始問題問爲什麼兩個具有SharedSizeGroup的網格在滿足某些條件(調整右側網格中的TextBlock的大小)時未調整到相同高度。我舉了他的例子並進行了擴展,因爲我懷疑它與測量/安排週期有關。

事實證明,它的確與測量和排列有關。其實,它與不是做一個措施。 我覺得這可能至少是一個問題,如果不是一個錯誤,但希望對行爲有一個解釋。

下面簡要介紹了會發生什麼情況(花色顏色僅供演示使用)。

啓動
兩個網格都有三行,每行包含一個TextBlock。中間一行是SharedSizeGroup。中間行的文本綁定到其TextBlock的ActualHeight,初始Height屬性被硬編碼爲您看到的值。網格下方的數字表示該網格的ActualHeight。請注意,左側網格的BackgroundColor爲綠色。

Startup

增加右側的TextBlock
在右側網格的尺寸增大,你可以看到,無論網格調整到新的高度,由於SharedSizeGroup。右側的列反映網格的「測量」和「排列」調用。

Increased In Size

降低右側的TextBlock但仍大於左側的TextBlock
在右側網格的尺寸減小,但仍高於硬編碼TextBlock的大小的左側,由於SharedSizeGroup的原因,您可以看到兩個網格再次調整到新的高度。右側的列反映網格的「測量」和「排列」調用。

Decreased to Minimum Size

降低左側TextBlock的右側的TextBlock不得超過SIZE
在右側網格的尺寸減小,小於的硬編碼TextBlock的大小左側,可以看到左側網格不會減小到「正確」大小,如通過查看底部網格的綠色背景所證明的,以及網格大小爲150而不是130

如果您查看右側的信息,您會注意到左側的網格進行了排列,但沒有做一個措施。

Decreased Past Size


下面是示例代碼複製的問題。

InfoGrid和InfoGridEventArgs類

using System.Windows; 
using System.Windows.Controls; 
namespace GridMeasureExample 
{ 
    class InfoGrid : Grid 
    { 
     protected override Size ArrangeOverride(Size arrangeSize) 
     { 
      CallReportInfoEvent("Arrange"); 
      return base.ArrangeOverride(arrangeSize); 
     } 
     protected override Size MeasureOverride(Size constraint) 
     { 
      CallReportInfoEvent("Measure"); 
      return base.MeasureOverride(constraint); 
     } 
     public event EventHandler<InfoGridEventArgs> ReportInfo; 
     private void CallReportInfoEvent(string message) 
     { 
      if (ReportInfo != null) 
       ReportInfo(this, new InfoGridEventArgs(message)); 
     } 
    } 
    public class InfoGridEventArgs : EventArgs 
    { 
     private InfoGridEventArgs() 
     { 
     } 
     public InfoGridEventArgs(string message) 
     { 
      this.TimeStamp = DateTime.Now; 
      this.Message = message; 
     } 
     public DateTime TimeStamp 
     { 
      get; 
      private set; 
     } 
     public String Message 
     { 
      get; 
      private set; 
     } 
    } 
} 

主窗口XAML

<Window x:Class="GridMeasureExample.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:GridMeasureExample" 
     Title="SharedSizeGroup" Height="500" Width="500"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 

     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
      <RowDefinition Height="Auto" /> 
     </Grid.RowDefinitions> 

     <StackPanel Grid.Column="0" 
        Grid.Row="0" 
        Orientation="Horizontal" 
        HorizontalAlignment="Left" 
        VerticalAlignment="Top" 
        Grid.IsSharedSizeScope="True"> 

      <StackPanel Orientation="Vertical" Width="100"> 
       <local:InfoGrid x:Name="grid1" Background="Green" ShowGridLines="True"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="15" /> 
         <RowDefinition SharedSizeGroup="Group1" /> 
         <RowDefinition Height="15" /> 
        </Grid.RowDefinitions> 
        <TextBlock Background="Blue" Grid.Row="0" Text="Row 0"/> 
        <TextBlock Background="Red" Grid.Row="1" Name="textBlock1" Height="100" 
          Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/> 
        <TextBlock Background="Blue" Grid.Row="2" Text="Row 2" /> 
       </local:InfoGrid> 
       <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid1}" /> 
      </StackPanel> 

      <StackPanel Orientation="Vertical" Width="100"> 
       <local:InfoGrid x:Name="grid2" Background="Yellow" ShowGridLines="True"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="15" /> 
         <RowDefinition SharedSizeGroup="Group1" /> 
         <RowDefinition Height="15" /> 
        </Grid.RowDefinitions> 
        <TextBlock Background="Orange" Grid.Row="0" Text="Row 0" /> 
        <TextBlock Background="Purple" Grid.Row="1" Name="textBlock2" Height="150" 
          Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/> 
        <TextBlock Background="Orange" Grid.Row="2" Text="Row 2" /> 
       </local:InfoGrid> 
       <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid2}" /> 
      </StackPanel> 

     </StackPanel> 

     <ListBox x:Name="lstInfo" 
       Grid.Column="1" 
       Grid.Row="0" 
       Margin="10,0,0,0" 
       HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch" /> 

     <UniformGrid Grid.Column="0" 
        Grid.Row="1" 
        Grid.ColumnSpan="2" 
        Columns="2" 
        HorizontalAlignment="Center" 
        Margin="5"> 
      <Button x:Name="btnIncrease" Margin="4,0">Increase</Button> 
      <Button x:Name="btnDecrease" Margin="4,0">Decrease</Button> 
     </UniformGrid> 

    </Grid> 

</Window> 

主窗口構造(僅在後臺代碼)

公共窗口1() { InitializeComponent();

btnIncrease.Click += (s, e) => 
     { 
      lstInfo.Items.Add(String.Format("{0} Increase Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff"))); 
      textBlock2.Height += 30; 
     }; 
    btnDecrease.Click += (s, e) => 
     { 
      lstInfo.Items.Add(String.Format("{0} Decrease Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff"))); 
      if (textBlock2.ActualHeight >= 30) 
       textBlock2.Height -= 30; 
     }; 

    grid1.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Left Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message)); 
    grid2.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Right Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message)); 
} 

回答