StackPanel
のすべてのアイテムの高さを知りたい。
違いは何ですか:
Height
-要素の推奨される高さを取得または設定します。ActualHeight
-この要素のレンダリングされた高さを取得します。 (読み取り専用)ExtentHeight
-エクステントの垂直サイズを含む値を取得します。 (読み取り専用)ViewportHeight
-コンテンツのビューポートの垂直方向のサイズを含む値を取得します。 (読み取り専用)DesiredSize
-レイアウトプロセスのメジャーパス中にこの要素が計算したサイズを取得します。 (読み取り専用)RenderSize
-この要素の最終的なレンダリングサイズを取得(または設定しますが、備考を参照)します。MSDNから:
高さ
要素の推奨高さを取得または設定します。プロパティ値:
Double
-要素の高さ(デバイスに依存しない単位)(単位あたり1/96インチ)。要素の高さ(デバイスに依存しない単位)(単位あたり1/96インチ)。
ActualHeight(読み取り専用)
この要素のレンダリングされた高さを取得します。プロパティ値:
Double
-デバイスに依存しない単位の値としての要素の高さ(単位あたり1/96インチ)。このプロパティは、他の高さ入力とレイアウトシステムに基づいて計算された値です。この値は、実際のレンダリングパスに基づいてレイアウトシステム自体によって設定されるため、入力変更の基礎となる Height などのプロパティの設定値よりもわずかに遅れる場合があります。
ActualHeightは計算値であるため、レイアウトシステムによるさまざまな操作の結果として、複数または増分の変更が報告される可能性があることに注意してください。レイアウトシステムは、子要素に必要な測定スペース、親要素による制約などを計算している場合があります。
ExtentHeight(読み取り専用)
エクステントの垂直サイズを含む値を取得します。プロパティの高さ:
Double
-エクステントの垂直方向のサイズを表すDouble。戻り値は、デバイスに依存しないピクセルで説明されています。
ViewportHeight(読み取り専用)
コンテンツのビューポートの垂直方向のサイズを含む値を取得します。プロパティ値:
Double
-コンテンツのビューポートの垂直方向のサイズを表すDouble。戻り値は、デバイスに依存しないピクセルで説明されています。
DesiredSize(readonly)
レイアウトプロセスのメジャーパス中にこの要素が計算したサイズを取得します。プロパティ値:
Size
-計算されたサイズ。これがアレンジパスの目的のサイズになります。このプロパティによって返される値は、IsMeasureValidプロパティの値がtrueの場合にのみ有効な測定値になります。
通常、DesiredSizeは、ArrangeOverride、MeasureOverride、OnRenderなどのレイアウト動作オーバーライドを実装するときに測定要素の1つとしてチェックされます(OnRenderの場合、代わりにRenderSizeをチェックできますが、これは実装によって異なります)。シナリオによっては、DesiredSizeが実装ロジックによって完全に尊重され、DesiredSizeの制約が適用される場合があり、そのような制約によって、親要素または子要素のいずれかの他の特性も変更される場合があります。たとえば、スクロール可能な領域をサポートするコントロール(ただし、スクロール可能な領域を既に有効にしているWPFフレームワークレベルのコントロールから派生しないことを選択する)は、使用可能なサイズをDesiredSizeと比較できます。次に、コントロールは、そのコントロールのUIでスクロールバーを有効にする内部状態を設定できます。または、特定のシナリオでは、DesiredSizeも無視される可能性があります。
RenderSizeこの要素の最終的なレンダリングサイズを取得します。
プロパティ値:
Size
-この要素のレンダリングサイズ。このプロパティは、OnRenderやGetLayoutClipなどのレイアウトシステムオーバーライド内で適用可能なレンダーサイズを確認するために使用できます。
より一般的なシナリオは、クラスハンドラーのオーバーライドまたはOnRenderSizeChangedイベントを使用してSizeChangedイベントを処理することです。
私の場合、StackPanel
内のすべてのアイテムのdesiredの高さを知りたいです。
言い換えると、StackPanel内のすべてのアイテムの高さを(描画する前に)知りたいのですが、それらがパネルからオーバーフローした場合は、
StackPanelに確実に収まるようにするアイテム。
つまり、resizeイベント中にdesiredheight(ExtentHeight?DesiredSize?)を取得したいということです( SizeChanged ? LayoutUpdated ?)-描画が行われる前(したがって、より高速です)。
これらのプロパティのほとんどはゼロを返します。したがって、これらのプロパティが何を意味するのかについては、私が知らず、ドキュメントで説明されていないことをある程度理解していることは明らかです。
ご存知のように、StackPanel
は[Panel]オブジェクトです。各パネルは、2つの方法で子と通信して、最終的なサイズと位置を決定します。最初のメソッドはMeasureOverride
で、2番目のメソッドはArrangeOverride
です。
MeasureOveride
は、各子に、指定された空き容量で希望のサイズを尋ねます。 ArrangeOverride
は、測定が完了した後に子を配置します。
スタックパネルを作成しましょう:
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
の最終的なサイズを表します。
ActualHeight
はRenderSize.Height
とまったく同じです。これらのプロパティを信頼するには、 LayoutUpdated イベントのイベントハンドラー内でのみアクセスする必要があります。
ViewPortHeight
こちらをご覧くださいExtentHeight
こちらをご覧くださいRenderSizeとActualHeightが一時的に異なる値を持つ可能性があることを除いて、上記の答えは正しいです。 RenderSizeはOnRenderの前に設定されますが、ActualHeightは、WPFがそのコントロールのレイアウトとレンダリング処理を完了すると設定されます。最後に、LayoutUpdatedが発生します。
したがって、RenderSizeはOnRender内で使用できますが、ActualHeightには、レイアウトが開始される前の古い値が引き続き含まれます。
シーケンスは次のようになります。
MeasureOverride() => sets DesiredSize
ArrangeOverride() => sets RenderSize
OnRender()
WPFは、このシーケンスを数回実行する場合があります(再帰)。すべてが解決すると、以下が実行されます。
ActualHeight = RenderSize.Height
ActualHeightは、最初のレイアウトが完了した後、いつでも(!)アクセスできます。ただし、測定、配置、およびレンダリングのレイアウトプロセス自体は除きます。 WPFは、レイアウト処理が実行される前にコードが完了することを保証します。