Как установить DesiredSize больше, чем ConstraintSize, используя метод MeasureOverride
У меня есть пользовательский элемент управления, который загружает внутренний набор элементов управления в зависимости от конфигурации пользователя. Внутренний набор элементов управления может содержать два типа элементов управления - некоторые из них имеют пользовательское присоединенное логическое свойство, которое говорит о том, что внутренний элемент управления может занимать только свое собственное желаемое пространство (предоставляя ложное значение по умолчанию), или элемент управления может занимать все оставшееся пространство (истинное значение).
Во внешнем контроле метод MeasureOverride переопределяется так же, как и во внутренних элементах управления. Внешний элемент управления вызывает метод Measure для всех дочерних элементов, который имеет значение по умолчанию для присоединенного свойства со значением double.InfinitePositive в качестве высоты ограничения. Дочерние элементы, для которых присоединенное свойство равно true, измеряются с (оставшееся пространство / количество дочерних элементов с прикрепленным свойством, равным true) как высота размера ограничения.
Все работает как положено. Внутренние элементы управления должным образом измерены, но здесь возникает проблема, если высота ограничения меньше вычисленной высоты внутреннего элемента управления. В этом случае после вызова меры для внутреннего элемента управления child.DesiredSize.Height равно ограничение, а child.ActualHeight равно значению высоты выходного размера дочернего MeasureOverride.
Как я могу сказать внешнему элементу управления, что требуемый размер дочернего элемента является выходным значением из метода child.MeasureOverrride?
Пример кода приведен здесь: Метод внешнего управления MeasureOverride:
protected override Size MeasureOverride(Size availableSize)
{
//size which can be used as constraint for children
Size constraintSize = new Size(availableSize.Width, double.PositiveInfinity);
//FixedElements has attached property value equal to false
foreach (FrameworkElement child in FixedElements)
{
child.Measure(constraintSize);
}
double fixedElementDesiredHeights = FixedElements.Sum(element => element.DesiredSize.Height);
//fixed element heights are higher than desired height
if (fixedElementDesiredHeights > DesiredMaxHeight)
{
foreach (FrameworkElement stretchedElement in StretchedElements)
{
stretchedElement.Measure(constraintSize);
}
}
else
{
//DesiredMaxHeight is expected height of outer value
var difference = DesiredMaxHeight - fixedElementDesiredHeights;
var visibleStretchedElements = StretchedElements.Count(element => element.IsVisible);
var stretchedSize = new Size(availableSize.Width, visibleStretchedElements == ZERO ? difference : difference / visibleStretchedElements);
foreach (FrameworkElement stretchedElement in StretchedElements)
{
stretchedElement.Measure(stretchedSize);
//if stretchedSize is smaller than output value
//from stretchedElement MeasureOverride method,
//stretchedElement.DesiredSize is equal to stretchedSize.
//But I expect stretchedElement.DesiredSize
//to be the same as
//stretchedElement MeasureOverride output value.
}
}
double stretChableElementsDesiredHeights = StretchedElements.Sum(element => element.DesiredSize.Height);
double height = fixedElementDesiredHeights + stretChableElementsDesiredHeights;
var outputSize = new Size(availableSize.Width, height);
return outputSize;
}