2011-06-19 140 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確保任何代碼在佈局處理運行之前完成。

相關問題