如何使用MeasureOverride方法将DesiredSize设置为大于ConstraintSize

时间:2015-05-11 09:50:46

标签: wpf layout measurement measureoverride

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

在外部控制中,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;
    }

0 个答案:

没有答案