Wpf Stackpanel:高度与实际高度与伸展高度与视口高度与所需大小与渲染大小

Wpf Stackpanel:高度与实际高度与伸展高度与视口高度与所需大小与渲染大小,wpf,layout,height,scaling,stackpanel,Wpf,Layout,Height,Scaling,Stackpanel,我想知道我的StackPanel中所有项目的高度 以下两者之间的区别是什么: -获取或设置元素的建议高度 -获取此元素的渲染高度。(只读) -获取包含扩展数据块垂直大小的值。(只读) -获取一个值,该值包含内容视口的垂直大小。(只读) -获取此元素在布局过程的度量过程中计算的大小。(只读) -获取(或设置,但请参见备注)此元素的最终渲染大小 从MSDN: 获取或设置元素的建议高度 属性值:Double—元件的高度,单位为独立于设备的单位(每单位1/96英寸) 元件的高度,以设备独立单位表

我想知道我的
StackPanel
中所有项目的高度

以下两者之间的区别是什么:

  • -获取或设置元素的建议高度
  • -获取此元素的渲染高度。(只读)
  • -获取包含扩展数据块垂直大小的值。(只读)
  • -获取一个值,该值包含内容视口的垂直大小。(只读)
  • -获取此元素在布局过程的度量过程中计算的大小。(只读)
  • -获取(或设置,但请参见备注)此元素的最终渲染大小

从MSDN:


获取或设置元素的建议高度

属性值:
Double
—元件的高度,单位为独立于设备的单位(每单位1/96英寸)

元件的高度,以设备独立单位表示(每单位1/96英寸)

(只读)
获取此元素的渲染高度

属性值:
Double
-元素高度,以设备独立单位表示(每单位1/96英寸)

此特性是基于其他高度输入和布局系统计算的值。该值由布局系统本身根据实际渲染过程设置,因此可能会稍微滞后于属性的设置值,例如作为输入更改基础的属性

因为ActualHeight是一个计算值,所以您应该知道,由于布局系统的各种操作,可能会有多个或增量报告的更改。布局系统可能正在计算子图元所需的度量空间、父图元的约束等

(只读)
获取一个值,该值包含扩展数据块的垂直大小

属性高度:
Double
-表示数据块垂直大小的双精度

返回值以与设备无关的像素表示

(只读)
获取一个值,该值包含内容视口的垂直大小

属性值:
Double
—表示内容视口垂直大小的双精度值

返回值以与设备无关的像素表示

(只读)
获取此元素在布局过程的度量过程中计算的大小

属性值:
Size
-计算的大小,它将成为排列过程所需的大小

只有IsMeasureValid属性的值为true时,此属性返回的值才是有效的度量值

当您实现布局行为替代(如ArrangeOverride、MeasureOverride或OnRender)时,DesiredSize通常作为度量因素之一进行检查(在OnRender情况下,您可以改为检查RenderSize,但这取决于您的实现)。根据场景的不同,DesiredSize可能会被您的实现逻辑完全遵守,DesiredSize上的约束可能会被应用,并且这些约束也可能会更改父元素或子元素的其他特征。例如,支持可滚动区域的控件(但选择不从已启用可滚动区域的WPF框架级控件派生)可以将可用大小与DesiredSize进行比较。然后,该控件可以设置一个内部状态,在该控件的UI中启用滚动条。或者,DesiredSize也可能在某些场景中被忽略

获取此元素的最终渲染大小

属性值:
Size
-此元素的渲染大小

此属性可用于检查布局系统替代(如OnRender或GetLayoutClip)中的适用渲染大小

更常见的场景是使用类处理程序重写或OnRenderSizeChanged事件处理SizeChanged事件


就我而言,我想知道
StackPanel
中所有项目的所需高度

换句话说:我想知道StackPanel中所有项目的高度(在绘图之前),如果它们溢出面板,我会

  • 删除
  • 收缩
  • 鳞片
  • 调整
项目,以确保它们适合堆叠面板

这意味着我可能希望在任何绘图之前,在调整大小事件(??)期间获得所需的高度(ExtentheLight?DesiredSize?)(因此速度更快)


大多数属性返回零;因此,很明显,我对这些属性的含义有一些理解,但我不知道,也没有在文档中解释。

正如您所知,
StackPanel
是一个[Panel]对象。每个面板通过两种方法与其子面板进行通信,以确定最终尺寸和位置。 第一种方法是
MeasureOverride
,第二种方法是
ArrangeOverride

MeasureOveride
要求每个孩子在给定的可用空间内获得所需的大小。
ArrangeOverride
在测量完成后安排子项

让我们创建一个stackpanel:

public class AnotherStackPanel : Panel
{
    public static readonly DependencyProperty OrientationProperty =
        DependencyProperty.Register(“Orientation”, typeof(Orientation),
        typeof(SimpleStackPanel), new FrameworkPropertyMetadata(
        Orientation.Vertical, FrameworkPropertyMetadataOptions.AffectsMeasure));

    public Orientation Orientation
    {
        get { return (Orientation)GetValue(OrientationProperty); }
        set { SetValue(OrientationProperty, value); }
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        Size desiredSize = new Size();

        if (Orientation == Orientation.Vertical)
            availableSize.Height = Double.PositiveInfinity;
        else
            availableSize.Width = Double.PositiveInfinity;
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                child.Measure(availableSize);

                if (Orientation == Orientation.Vertical)
                {
                    desiredSize.Width = Math.Max(desiredSize.Width,
                    child.DesiredSize.Width);
                    desiredSize.Height += child.DesiredSize.Height;
                }
                else
                {
                    desiredSize.Height = Math.Max(desiredSize.Height,
                    child.DesiredSize.Height);
                    desiredSize.Width += child.DesiredSize.Width;
                }
            }
        }
        return desiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        double offset = 0;
        foreach (UIElement child in this.Children)
        {
            if (child != null)
            {
                if (Orientation == Orientation.Vertical)
                {               
                    child.Arrange(new Rect(0, offset, finalSize.Width,
                    child.DesiredSize.Height));                 
                    offset += child.DesiredSize.Height;
                }
                else
                {                   
                    child.Arrange(new Rect(offset, 0, child.DesiredSize.Width,
                    finalSize.Height));
                    offset += child.DesiredSize.Width;
                }
            }
        }
        return finalSize;
    }
}
  • 所需的
    尺寸
    (尺寸
    MeasureOverride
    )返回的是总和 儿童尺寸的方向 StackPanel和最大的 孩子在另一个方向

  • RenderSize
    表示最终 布局后堆叠面板的大小 完成了

  • 实际高度
    RenderSize.Height
对于这些属性,您应该仅在偶数范围内访问它们
MeasureOverride() => sets DesiredSize
ArrangeOverride() => sets RenderSize
OnRender()
ActualHeight = RenderSize.Height