Я пытаюсь сделать то, что я думал, будет простой панелью в 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>
Но вывод выглядит так:
Как видите, элементы обрезаются - в списках должны отображаться полосы прокрутки. Дочерние элементы не соответствуют размеру, указанному им в проходе аранжировки.
Из моих исследований кажется, что вы не можете назначить контролю меньший размер, чем в проходе меры .
Однако я не могу этого сделать, потому что Мне нужны результаты теста, чтобы узнать, какой размер дать детям в аранжировке .
Это похоже на ситуацию с курицей и яйцом. Не нарушен ли макет в WPF? Конечно, проход измерения должен быть именно таким: мера проход?