2011-06-19 212 views
21

我想知道所有项目的高度我的StackPanelStackpanel:高度vs ActualHeight vs ExtentHeight vs ViewportHeight vs DesiredSize vs RenderSize

之间有什么区别:

  • Height - 获取或设置元素的建议高度。
  • ActualHeight - 获取此元素的渲染高度。 (只读
  • ExtentHeight - 获取包含范围的垂直大小的值。 (只读
  • ViewportHeight - 获取一个包含内容视口垂直尺寸的值。 (只读
  • DesiredSize - 获取此元素在布局过程的度量传递期间计算的大小。 (只读
  • RenderSize - 获取(或设置,但请参阅备注)此元素的最终渲染大小。

从MSDN:

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

物业价值:Double - 元件的高度,与设备无关的单位(每单位1/96英寸)。

元件的高度,与设备无关单位(每个单位1/96英寸)。

 

ActualHeight只读
获取此元素的呈现高度。

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

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

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

 

ExtentHeight只读
获取包含的程度的垂直尺寸的值。

物业高度:Double - 表示范围的垂直大小的Double。

返回的值在“设备无关像素”中描述。

 

ViewportHeight只读
获取包含内容的视区的垂直尺寸的值。

属性值:Double - 表示内容视口的垂直大小的Double。

返回的值在“设备无关像素”中描述。

 

DesiredSize只读
获取此元素的布局处理的测量处理过程中计算的大小。

物业价值:Size - 计算的大小,它成为安排过程所需的大小。

如果IsMeasureValid属性的值为true,则此属性返回的值将仅为有效的度量值。

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

 

RenderSize 获取此元素的最终呈现大小。

物业价值:Size - 此元素的渲染大小。

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

更常见的情况是使用类处理程序重写或OnRenderSizeChanged事件处理SizeChanged事件。


在我的情况,我想知道在StackPanel所有项目的所需高度。

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

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

项目,以确保它们适合在StackPanel的

这意味着我可能要一个调整事件(SizeChangedLayoutUpdated?)中,以获得所需的高度(ExtentHeight DesiredSize?) - 任何绘图发生之前(因此它的速度更快)。

大多数这些属性返回零;所以显然有一些理解这些属性意味着我不知道,并没有在文档中解释。

回答

14

如您所知,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; 
    } 
} 
  • DesiredSize(由MeasureOverride返回的大小 )是 StackPanel的方向和最大 孩子在大小尺寸的孩童的总和 其他方向。

  • RenderSize代表布局 后最终 大小StackPanel的完成。

  • ActualHeightRenderSize.Height完全相同。

对于依赖这些属性,只能在LayoutUpdated事件的事件处理程序中访问它们。

3

上面的回答是正确的,但RenderSize和的ActualHeight可以暂时不同的值。 RenderSize在OnRender之前被设置,而一旦WPF完成了该控件的布局和渲染处理,就设置了ActualHeight。最后,LayoutUpdated得到提升。

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

的顺序是这样的:

MeasureOverride() => sets DesiredSize 
ArrangeOverride() => sets RenderSize 
OnRender() 

WPF可以执行这个序列几次(递归)。一旦一切都解决了,下面的被执行:

ActualHeight = RenderSize.Height 

的ActualHeight可以访问任何时候的第一个布局后完成,除了在布局过程本身措施,安排和渲染(!)。 WPF确保任何代码在布局处理运行之前完成。

相关问题