I have a custom control, which load inner control set based on user configuration. Inner control set can contain two types of controls - some of them has custom attached boolean property, which says that inner control can take only it's own desired space (providing false value by default) or control can take all remaining space (true value).
In outer control MeasureOverride method is overriden as well as in inner controls. Outer control calls Measure method on all children which has default value of attached property with double.InfinitePositive value as constraint height. Children, where attached property equals to true are measured with (remaining space/number of children with attached property equal to true) as constraint size height.
Everything works as expected. Inner controls are properly measured, but here is a problem if constraint height is smaller than inner control calculated height. In that case, after calling measure on inner control child.DesiredSize.Height is equal to constraint and child.ActualHeight is equal to child MeasureOverride output size height value.
How can I say to outer control that child's Desired size is output value from child.MeasureOverrride method?
Example of code goes here: MeasureOverride method of outer control:
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;
}