当SharedSizeGroup的行高更改时,网格高度无法正确调整

时间:2010-10-05 15:12:30

标签: c# wpf grid

我有两个网格,每个网格有三行。每个网格的第一行和最后一行具有固定高度,而中间行具有自动高度并使用SharedSizeGroup共享其高度。

首先,右侧网格的内容决定了大小组的高度。当右侧网格的内容缩小以使左侧网格的内容确定大小组的高度时,左侧网格的整体大小未正确调整。

请参阅以下示例应用。单击“增加”按钮可增加右侧网格中文本块的大小。左侧网格的大小相应地改变。现在缩小尺寸。当文本块变得小于左网格中的文本块时,左网格的总大小不会缩小。这是一个错误还是我错过了什么?

<StackPanel Orientation="Horizontal" Grid.IsSharedSizeScope="True">
    <StackPanel Orientation="Vertical" Width="100">
        <Grid Background="Green">
            <Grid.RowDefinitions>
                <RowDefinition Height="15" />
                <RowDefinition SharedSizeGroup="Group1" />
                <RowDefinition Height="15" />
            </Grid.RowDefinitions>
            <TextBlock Background="Blue" Grid.Row="0" />
            <TextBlock Background="Red" Grid.Row="1" Name="textBlock1" Height="100" />
            <TextBlock Background="Blue" Grid.Row="2" />
        </Grid>
        <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid1}" />
    </StackPanel>
    <StackPanel Orientation="Vertical" Width="100">
        <Grid Background="Green">
            <Grid.RowDefinitions>
                <RowDefinition Height="15" />
                <RowDefinition SharedSizeGroup="Group1" />
                <RowDefinition Height="15" />
            </Grid.RowDefinitions>
            <TextBlock Background="Blue" Grid.Row="0" />
            <TextBlock Background="Red" Grid.Row="1" Name="textBlock2" Height="150" />
            <TextBlock Background="Blue" Grid.Row="2" />
        </Grid>
        <TextBlock Text="{Binding Path=ActualHeight, ElementName=grid2}" />
    </StackPanel>
    <Button Height="24" Click="Button_Click_1" VerticalAlignment="Top">Increase</Button>
    <Button Height="24" Click="Button_Click_2" VerticalAlignment="Top">Decrease</Button>
</StackPanel>

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    textBlock2.Height += 30;
}

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    textBlock2.Height -= 30;
}

1 个答案:

答案 0 :(得分:2)

行保持相同的高度 - 第二个TextBlock的大小正在变化,而第一个TextBlock的大小保持为100。

为了证明这一点,请进行以下更改:

  • ShowGridLines="True"添加到每个网格
  • 更改已命名的TextBlocks以将其ActualHeight显示为其文本:

        <TextBlock Background="Red" Grid.Row="1" Name="textBlock2" Height="150"
                   Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
    

您将看到SharedSizeGroup行将是两个TextBlocks的最大ActualHeight。

更新:显示正在发生的事情的短项目
我创建了一个快速肮脏的项目来展示正在发生的事情。事实证明,当右网格小于原始大小时,左网格执行排列而不是测量。我不确定我完全理解这一点 - 我have posted a follow-up question使用同样的解决方案。

这是我根据您的原创创建的解决方案。它简单地将基本网格包装在一个自定义类中,该类在调用Measure和Arrange时调出信息(通过事件)。在主窗口中,我只是将该信息放入列表框中。

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>

主窗口构造函数(仅代码隐藏代码)

public Window1()     {         的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));
}