Измерение/упорядочивание сеток с помощью SharedSizeGroup

Кажется, есть небольшая проблема с двумя сетками, содержащими элементы, указанные определенным образом, и SharedSizeGroup.

Этот вопрос является ответом на предыдущий вопрос от пользователя DH Я попытался ответить. Простите за длину, но это помогает наглядно продемонстрировать проблему.

Его первоначальный вопрос заключался в том, почему две сетки с SharedSizeGroup не изменяются до одинаковой высоты при выполнении определенных условий (изменение размера TextBlock в правой части сетки). Я взял его пример и расширил его, потому что подозревал, что это связано с циклом «Измерить/Упорядочить».

Оказывается, на самом деле это связано с «Измерить и упорядочить». На самом деле, это связано с тем, что не выполняется измерение. Я чувствую, что это может быть как минимум проблемой, если не ошибкой, но хотел бы получить объяснение поведения.

Вот краткий обзор того, что происходит (яркие цвета только для демонстрационных целей).

Запуск
Обе сетки имеют три строки, каждая из которых содержит текстовый блок. Средняя строка принадлежит SharedSizeGroup. Текст средней строки привязан к ActualHeight его TextBlock, а начальное свойство Height жестко запрограммировано для отображаемых значений. Числа под сетками представляют собой ActualHeight этой сетки. Обратите внимание, что BackgroundColor левой сетки — зеленый.

Автозагрузка

Увеличение правого текстового блока
Когда правая сетка увеличивается в размере, вы можете видеть, что обе сетки изменяются до новой высоты из-за SharedSizeGroup. Столбец справа отражает вызовы Measure и Arrange для сеток.

Увеличен в размере

Уменьшение правого текстового блока, но все равно больше, чем левого текстового блока
Когда правая сетка уменьшена в размере, но все еще больше, чем размер жестко запрограммированного текстового блока слева вы можете видеть, что обе сетки снова изменяются до новой высоты из-за SharedSizeGroup. Столбец справа отражает вызовы Measure и Arrange для сеток.

Уменьшен до минимального размера

Уменьшение размера правого текстового блока меньше, чем размер левого текстового блока
Когда размер правой сетки уменьшается, размер меньше, чем размер жестко запрограммированного текстового блока слева , видно, что левая сетка не уменьшается до «правильного» размера, о чем свидетельствует зеленый фон сетки внизу и тот факт, что размер сетки равен 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>

Конструктор главного окна (только код в коде программной части)

общественное 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));
}

person Wonko the Sane    schedule 08.10.2010    source источник


Ответы (1)


По данным Microsoft, это баг.

Похоже, это ошибка в WPF, и Microsoft знает об этом и ищет решение.

Если вам нужна помощь с обходным решением, обратитесь в службу поддержки Майкрософт по адресу

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

Вы также можете отправить отзыв об ошибке для WPF по этой проблеме на…

http://connect.microsoft.com/VisualStudio

Я отправил это как ошибку в Подключить сайт.

person Wonko the Sane    schedule 15.10.2010