2

我有一个自定义控件,它根据用户配置加载内部控件集。内部控件集可以包含两种类型的控件 - 其中一些具有自定义附加的布尔属性,这表示内部控件只能占用它自己想要的空间(默认提供 false 值)或控件可以占用所有剩余空间(true 值)。

在外部控件中,MeasureOverride 方法被覆盖以及在内部控件中。外部控件对所有具有附加属性的默认值的子控件调用 Measure 方法,并将 double.InfinitePositive 值作为约束高度。附加属性等于 true 的子级以(剩余空间/附加属性等于 true 的子级数)作为约束大小高度进行测量。

一切都按预期工作。内部控件已正确测量,但如果约束高度小于内部控件计算高度,则会出现问题。在这种情况下,在内部控件上调用 measure 之后 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;
    }
4

0 回答 0