首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Stackpanel:身高vs ActualHeight vs ExtentHeight vs ViewportHeight vs DesiredSize vs RenderSize

Stackpanel:身高vs ActualHeight vs ExtentHeight vs ViewportHeight vs DesiredSize vs RenderSize
EN

Stack Overflow用户
提问于 2011-06-19 14:48:41
回答 2查看 22.1K关注 0票数 26

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

在以下方面有何区别:

  • Height -获取或设置元素的建议高度。
  • ActualHeight -获取此元素的呈现高度。(只读)
  • ExtentHeight -获取一个包含区域垂直大小的值。(只读)
  • ViewportHeight -获取一个包含内容视图端口垂直大小的值。(只读)
  • DesiredSize -获取此元素在布局处理的度量值传递期间计算的大小。(只读)
  • RenderSize -获取(或设置,但请参见备注)此元素的最终呈现大小。

来自MSDN:

高度 获取或设置元素的建议高度。 属性值:Double -元素的高度,以独立于设备的单位(每单位1/96英寸)。 单元的高度,以独立于设备的单位(每单位1/96英寸)。

ActualHeight (只读) 获取此元素的呈现高度。属性值:Double -元素的高度,作为独立于设备的单元的值(每单位1/96英寸)。 此属性是基于其他高度输入和布局系统的计算值。该值是由布局系统本身根据实际呈现传递设置的,因此可能稍微落后于作为输入更改基础的属性(如高度 )的设置值。 因为ActualHeight是一个计算值,因此您应该注意到,由于布局系统的各种操作,可能会对其进行多次或增量报告的更改。布局系统可能正在计算子元素所需的度量空间、父元素的约束等。

ExtentHeight (只读) 获取一个包含区域垂直大小的值。属性高度:Double -表示范围的垂直大小的双倍。 返回的值在设备独立像素中描述。

ViewportHeight (只读) 获取一个值,该值包含内容的视图端口的垂直大小。 属性值:Double -表示内容视图的垂直大小的双倍。返回的值在设备独立像素中描述。

DesiredSize (只读) 获取此元素在布局处理的度量值传递期间计算的大小。 属性值:Size --计算出的大小,它将成为排列传递所需的大小。 只有当IsMeasureValid属性的值为真时,此属性返回的值才是有效的度量。 当您实现ArrangeOverride、MeasureOverride或OnRender等布局行为重写时,通常会将ArrangeOverride作为度量因素之一进行检查(在OnRender情况下,您可能会检查RenderSize,但这取决于您的实现)。根据场景的不同,您的实现逻辑可能完全遵守DesiredSize,可以应用DesiredSize上的约束,这些约束还可能改变父元素或子元素的其他特性。例如,支持滚动区域的控件(但选择不从已启用滚动区域的WPF框架级控件派生)可以将可用大小与DesiredSize进行比较。然后,控件可以设置一个内部状态,该状态启用该控件的UI中的滚动条。或者,在某些情况下,DesiredSize也可能被忽略。

RenderSize获得此元素的最终呈现大小。 属性值:Size -此元素的呈现大小。 此属性可用于检查布局系统重写(如OnRender或GetLayoutClip )中适用的呈现大小。 更常见的场景是使用类处理程序覆盖或SizeChanged事件处理OnRenderSizeChanged事件。

在我的例子中,我想知道所需的StackPanel中所有项目的高度。

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

  • 删除
  • 收缩
  • 规模
  • 调整

确保它们符合StackPanel的项目。

这意味着我可能想要达到所需的高度(ExtentHeight?DesiredSize?)在调整大小的事件(SizeChangedLayoutUpdated?)-在任何绘图发生之前(所以速度更快)。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-19 19:25:09

如您所知,StackPanel是一个Panel。每个面板通过两种方法与其子女沟通,以确定最终的大小和位置。第一个方法是MeasureOverride,第二个方法是ArrangeOverride

MeasureOveride要求每个子级在给定空间的情况下获得所需的大小。ArrangeOverride在测量完成后安排孩子。

让我们创建一个堆栈面板:

代码语言:javascript
运行
复制
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;
    }
}
  • DesiredSize (MeasureOverride返回的大小)是StackPanel方向上的子大小之和,另一个方向是最大子级的大小之和。
  • RenderSize表示布局完成后StackPanel的最终大小。
  • ActualHeightRenderSize.Height完全一样。

为了依赖这些属性,您应该只在LayoutUpdated事件的事件处理程序中访问它们。

  • 代表ViewPortHeight 看这儿
  • 代表ExtentHeight 看这儿
票数 15
EN

Stack Overflow用户

发布于 2014-02-11 09:58:11

上面的答案是正确的,除了RenderSize和ActualHeight可能有暂时不同的值。RenderSize在OnRender之前设置,而ActualHeight则是在WPF完成该控件的布局和呈现处理后设置的。在最后,LayoutUpdated会被提升。

因此,RenderSize可以在OnRender中使用,但是ActualHeight仍然具有布局开始前的旧值。

序列如下:

代码语言:javascript
运行
复制
MeasureOverride() => sets DesiredSize
ArrangeOverride() => sets RenderSize
OnRender()

WPF可能多次执行此序列(递归)。一旦解决了所有问题,就会执行以下操作:

代码语言:javascript
运行
复制
ActualHeight = RenderSize.Height

ActualHeight可以随时访问(!)在完成第一个布局之后,除了在布局过程本身的测量、安排和渲染之外。WPF确保在布局处理运行之前完成所有代码。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6403091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档