【问题标题】:Measure/Arrange Of Grids with SharedSizeGroup使用 SharedSizeGroup 测量/排列网格
【发布时间】:2010-10-08 14:34:10
【问题描述】:

两个包含以某种方式指定的元素的网格和 SharedSizeGroup 似乎有点问题。

这个问题是对来自user D.H.earlier question 的回应,我试图回答。原谅篇幅过长,但它有助于直观地展示问题。

他最初的问题是为什么两个具有 SharedSizeGroup 的网格在满足某些条件时没有调整到相同的高度(在右侧网格中调整 TextBlock 的大小)。我拿他的例子来扩展它,因为我怀疑它与 Measure/Arrange 循环有关。

事实证明,它确实与 Measure and Arrange 有关。实际上,它与 not 进行测量有关。 我觉得这可能至少是一个问题,如果不是错误的话,但希望对这种行为进行解释。

这里是所发生情况的简要概述(花哨的颜色仅用于演示目的)。

启动
两个网格都有三行,每行包含一个 TextBlock。中间一行是 SharedSizeGroup。中间行的文本绑定到其 TextBlock 的 ActualHeight,初始的 Height 属性硬编码为您看到的值。网格下方的数字代表该网格的实际高度。注意左边网格的BackgroundColor是绿色。

增加右侧文本块
当右侧网格的大小增加时,您可以看到两个网格都调整到新的高度,这是由于 SharedSizeGroup。右侧的列反映了网格的 Measure 和 Arrange 调用。

减小右侧 TextBlock 但仍大于左侧 TextBlock
当右侧网格的大小减小,但仍大于左侧硬编码 TextBlock 的大小时,您可以看到由于 SharedSizeGroup,两个网格再次调整到新的高度。右侧的列反映了网格的 Measure 和 Arrange 调用。

将右侧 TextBlock 减小到小于左侧 TextBlock 的大小
当右侧网格的大小减小到小于左侧硬编码 TextBlock 的大小时,您可以看到左侧网格没有减小到“适当”的大小,如下所示底部格子的绿色背景,格子的大小是150,不是130。

如果你看右边的信息,你会注意到左边的网格做了一个排列,但没有做一个测量。


这里是复制问题的示例代码。

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() { 初始化组件();

    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));
}

【问题讨论】:

    标签: wpf measurement measure


    【解决方案1】:

    According to Microsoft,这是一个错误。

    这似乎是 WPF 中的一个错误,并且 微软意识到了这一点,并且 调查解决方案。

    如果您需要解决方法方面的帮助, 请联系微软支持

    http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

    您还可以提交错误反馈 WPF 关于这个问题的...

    http://connect.microsoft.com/VisualStudio

    我已将此作为错误提交到 Connect site

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多