2010-10-08 62 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)); 
} 

回答