Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net WPF:测量是否有副作用? 情况:_.net_Wpf_Panel_Measureoverride_Arrangeoverride - Fatal编程技术网

.net WPF:测量是否有副作用? 情况:

.net WPF:测量是否有副作用? 情况:,.net,wpf,panel,measureoverride,arrangeoverride,.net,Wpf,Panel,Measureoverride,Arrangeoverride,我正在尝试为垂直排列的两个子项创建一个面板类StickyInfoPanel。两个项目中较低的项目高度应为100px。上部项目应消耗总可用高度的剩余部分 上面的项是一个滚动视图,其中有一个stackpanel和两个子项(upper1和upper2)。因此,每当stackpanel没有足够的空间时,垂直滚动条就会出现,如下图所示: 问题是: 虽然在排列阶段将正确的高度传递给上部项目,但其结果高度更高,因此不会显示滚动条。(见第二张截图) 只有当窗口进一步缩小,以便只能显示upper1时,才会出现滚

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

上面的项是一个滚动视图,其中有一个stackpanel和两个子项(upper1和upper2)。因此,每当stackpanel没有足够的空间时,垂直滚动条就会出现,如下图所示:

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

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

奇怪的是,当从
MeasureOverride
向项目传递正确的所需高度时,一切都按预期进行

从我的理解来看,措施过度应该是无副作用的,而事实显然并非如此。谁能解释一下,我在这里遗漏了什么

XAML:
因此,经过一些测量之后,这里是定制面板中生成的子元素大小的最终公式(这里的“最小”和“最大”操作符按元素工作):

实际尺寸=最大值(最小值(可用尺寸、期望尺寸、理论尺寸)、最终尺寸)

在哪里

  • actualSize是子元素的结果大小
  • availableSize是面板从其自身测量值传递到元素测量方法的大小
  • DesiredSize理论上是如果有无限空间可用,子元素将要占用的大小
  • finalSize是面板从其自身的ArrangeOverride传递给子元素的Arrange方法的大小
或者换言之:除非子元素需要更多的空间,并且承诺在MeasureOverride中有更多的空间,否则结果大小将始终是最终大小。在这种情况下,结果大小将是这两个值中的较小值


在ScrollViewer作为子元素时发现了这一点。我希望其他类的行为也一样。

为什么不使用网格?@Clemens,因为实际上我需要的更复杂。我只是尽量把它删去了。恐怕我不明白你的问题。在测量过程中,将可用大小传递给子元素。让
h
作为面板的总可用高度,那么第一个孩子的可用高度显然是
h-100
,第二个孩子的可用高度是剩余的
100
。好吧,我想这是两个问题:1)为什么项目忽略了我在ArrangeOverview中告诉它的内容?2)我在测量过程中传递给项目的某些内容如何影响结果?@FrankimWald,DockPanel满足您描述的布局要求。将下方的TextBock停靠在底部,让ScrollViewer填满剩余的空间。你证实了我的怀疑,即
测量
不是它应该具备的功能风格、无副作用的测量功能,但实际上已经参与了安排。缺少的是传达所有输入值与实际结果之间关系的清晰算法/公式。我担心它还没有完成。它可能仍然忽略了当子元素返回与DesiredSizeTheory(基于availableSize)不同的所需值时发生的微妙情况。我没时间想清楚。
<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; 
    }
}