我有一个自定义控件,它根据用户配置加载内部控件集。内部控件集可以包含两种类型的控件 - 其中一些具有自定义附加布尔属性,该属性表示内部控件只能占用自己想要的空间(默认情况下提供假值)或者控件可以占用所有剩余空间(真实的价值)。
在外部控制中,MeasureOverride方法和内部控件都被覆盖。外部控件调用所有具有附加属性默认值的子项的Measure方法,其double.InfinitePositive值作为约束高度。附属物等于真的儿童用约束尺寸高度(剩余空间/附属物等于真实的儿童数)来衡量。
一切都按预期工作。正确测量内部控制,但如果约束高度小于内部控制计算高度,则存在问题。在这种情况下,在内部控件child上调用measure之后.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;
}