开发者

Measure/Arrange Of Grids with SharedSizeGroup

开发者 https://www.devze.com 2023-01-19 18:52 出处:网络
There seems to be a bit of an issue with two grids containing elements specified in a certain way, and the SharedSizeGroup.

There seems to be a bit of an issue with two grids containing elements specified in a certain way, and the SharedSizeGroup.

This question is in response to an earlier question from user D.H. I attempted to answer. Forgive the length, but it helps to demonstrate the problem visually.

His original question asked why two grids with a SharedSizeGroup didn't resize to the same height when certain conditions were met (resizing a TextBlock in the right-side grid). I took his example and expanded it, because I suspected that it had to do with the Measure/Arrange cycle.

It turns out that it does, in fact, have to do with Measure and Arrange. Actually, it has to do with not doing a Measure. I feel that this may be at least an issue, if not a bug, but would like to have an explanation of the behavior.

Here is a quick overview of what happens (garish colors for demo purposes only).

Start Up

Both grids have three rows, each containing a TextBlock. The middle row is of SharedSizeGroup. The text of the middle row is bound to the ActualHeight of its TextBlock, with the initial Height property hard-coded to the values you see. The numbers below the grids represent the ActualHeight of that grid. Note that the BackgroundColor of the left grid is Green.

Measure/Arrange Of Grids with SharedSizeGroup

Increasing the Right-Side TextBlock

When the right-side grid is increased in size, you can see that both grids resize to the new height, due to the SharedSizeGroup. The column at the right reflects the Measure and Arrange calls of the grids.

Measure/Arrange Of Grids with SharedSizeGroup

Decreasing the Right-Side TextBlock But Still Greater Than Left-Side TextBlock

When the right-side grid is decreased in size, but still larger than the size of the hard-coded TextBlock of the left side, you can see that both grids again resize to the new height, due to the SharedSizeGroup. The column at the right reflects the Measure and Arrange calls of the grids.

Measure/Arrange Of Grids with SharedSizeGroup

Decreasing the Right-Side TextBlock Less Than Size of Left-Side TextBlock

When the right-side grid is decreased in size, less than the size of the hard-coded TextBlock of the left side, you can see that the left-side grid does not decrease to the "proper" size, as evidenced by seeing the Green background of the grid at the bottom, and the fact that the size of the grid is 150, not 130.

If you look at the info on the right, you will notice that the Left grid did an Arrange, but did not do a Measure.

Measure/Arrange Of Grids with SharedSizeGroup


Here is the example code to duplicate the issue.

InfoGrid and InfoGridEventArgs classes

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

Main Window 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" Wi开发者_高级运维dth="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>

Main Window Constructor (only code in code-behind)

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


According to Microsoft, it's a bug.

This appears to be a bug in WPF, and Microsoft is aware of it and investigating a solution.

If you need help with a workaround, please contact Microsoft Support at

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

You can also submit bug feedback for WPF regarding this issue at…

http://connect.microsoft.com/VisualStudio

I've submitted this as a bug on the Connect site.

0

精彩评论

暂无评论...
验证码 换一张
取 消