Проблемы с расположением / измерением - макет нарушен в WPF?

Я пытаюсь создать то, что, как я думал, будет простой панелью в WPF, которая имеет следующие свойства:

  • Если совокупный рост детей меньше доступной высоты, тогда все дочерние элементы отображаются на желаемой высоте.

  • Если совокупный рост детей превышает доступный рост, все дети уменьшаются на один и тот же процент роста, чтобы соответствовать.

Моя панель выглядит так:

public class MyStackPanel : Panel
{
    protected override Size MeasureOverride(Size availableSize)
    {
        Size requiredSize = new Size();

        foreach (UIElement e in InternalChildren)
        {
            e.Measure(availableSize);
            requiredSize.Height += e.DesiredSize.Height;
            requiredSize.Width = Math.Max(requiredSize.Width, e.DesiredSize.Width);
        }

        return new Size(
            Math.Min(availableSize.Width, requiredSize.Width),
            Math.Min(availableSize.Height, requiredSize.Height));
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        double requiredHeight = 0;

        foreach (UIElement e in InternalChildren)
        {
            requiredHeight += e.DesiredSize.Height;
        }

        double scale = 1;

        if (requiredHeight > finalSize.Height)
        {
            scale = finalSize.Height / requiredHeight;
        }

        double y = 0;

        foreach (UIElement e in InternalChildren)
        {
            double height = e.DesiredSize.Height * scale;
            e.Arrange(new Rect(0, y, finalSize.Width, height));
            y += height;
        }

        return finalSize;
    }
}

Мой тестовый XAML выглядит так:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="300" Width="300">
    <Window.Resources>
        <x:Array x:Key="Items" Type="{x:Type sys:String}">
            <sys:String>Item1</sys:String>
            <sys:String>Item2</sys:String>
            <sys:String>Item3</sys:String>
            <sys:String>Item4</sys:String>
        </x:Array>
    </Window.Resources>
    <local:MyStackPanel>
        <ListBox ItemsSource="{StaticResource Items}"/>
        <ListBox ItemsSource="{StaticResource Items}"/>
        <ListBox ItemsSource="{StaticResource Items}"/>
        <ListBox ItemsSource="{StaticResource Items}"/>
        <ListBox ItemsSource="{StaticResource Items}"/>
    </local:MyStackPanel>
</Window>

Но результат выглядит так:

Layout Problem

Как видите, элементы отсекаются - в списках должны отображаться полосы прокрутки . Дочерние элементы не соответствуют размеру, заданному им в проходе аранжировки.

Из моих исследований кажется, что вы не можете дать элементу управления меньший размер в проходе аранжировки, чем вы дали в проходе измерения .

Однако я не могу этого сделать, потому что мне нужны результаты передачи измерения, чтобы знать, какой размер передать дочерним элементам в передаче аранжировки .

Это похоже на ситуацию с курицей и яйцом. Макет в WPF нарушен? Несомненно, проход измерения должен быть именно таким, проходом тактом ?

13
задан Grokys 25 November 2011 в 13:42
поделиться