1

情况:

我正在尝试为StickyInfoPanel垂直布局的两个子项创建一个面板类。两项中较低的一项应为 100px 的高度。上面的项目将消耗剩余的总可用高度。

上面的项目是一个 ScrollView,里面有一个 stackpanel 和两个子项(upper1 和 upper2)。因此,只要堆栈面板没有足够的空间,就会出现垂直滚动条,如下图所示:

在此处输入图像描述

问题:

尽管在排列阶段将正确的高度传递给上部项目,但其结果高度更高,因此滚动条不会显示。(见第二张截图)

只有当窗口进一步缩小,只有upper1可以显示时,才会出现滚动条。但它的向下按钮仍然消失(见第三张截图)

奇怪的是,当将正确的所需高度传递给 from 的项目时MeasureOverride,一切都按预期工作。

据我了解,MeasureOverride 应该没有副作用,但显然不是。谁能解释一下,我在这里缺少什么?

在此处输入图像描述

在此处输入图像描述

XAML:

<Window x:Class="GridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:GridTest"
        Title="MainWindow" Height="190.57" Width="800">
    <local:StickyInfoPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
        <ScrollViewer Background="LightYellow" VerticalScrollBarVisibility="Auto" CanContentScroll="false">
            <StackPanel Margin="30 0" CanVerticallyScroll="False">
                <TextBlock Background="AliceBlue" Height="100">upper1</TextBlock>
                <TextBlock Background="Azure" Height="100">upper2</TextBlock>
            </StackPanel>
        </ScrollViewer>
        <TextBlock Background="Gainsboro" Height="100">Lower</TextBlock>
    </local:StickyInfoPanel>
</Window>

面板类:

class StickyInfoPanel : Panel
{
    public StickyInfoPanel()
        : base()
    {
    }
    protected override Size MeasureOverride(Size availableSize)
    {
        InternalChildren[0].Measure(availableSize);
        InternalChildren[1].Measure(availableSize);
        //this works:
        //InternalChildren[0].Measure(new Size(availableSize.Width, availableSize.Height - 100));
        return availableSize;
    }
    protected override Size ArrangeOverride(Size finalSize)
    {
        InternalChildren[0].Arrange(new Rect(new Point(0, 0),                      new Size(finalSize.Width, finalSize.Height - 100)));
        InternalChildren[1].Arrange(new Rect(new Point(0, finalSize.Height - 100), new Size(finalSize.Width, 100)));
        return finalSize; 
    }
}
4

1 回答 1

1

因此,经过一些测量后,这是自定义面板内生成的子元素大小的最终公式(最小值和最大值运算符在此处按元素工作):

actualSize = max( min( availableSize , desiredSizeTheoretical), finalSize )

在哪里

  • actualSize是子元素的结果大小
  • availableSize是面板从它自己的 MeasureOverride 传递给元素的 Measure 方法的大小
  • desiredSizeTheoretical是如果有无限可用空间,子元素想要占据的大小
  • finalSize是面板从其自身的 ArrangeOverride 传递给子元素的 Arrange 方法的大小

或者说:结果大小将始终为 finalSize,除非子元素需要更多空间并且在 MeasureOverride 中承诺提供更多空间。在这种情况下,结果大小将是这两个值中较小的一个。

已发现 ScrollViewer 作为子元素。我希望,其他类的行为也一样。

于 2018-07-25T14:22:57.127 回答