次の方法で共有


WPF グラフィックス レンダリングの概要

このトピックでは、WPF ビジュアル レイヤーの概要について説明します。 ここでは、WPF モデルでサポートをレンダリングするための Visual クラスの役割に重点を置いています。

視覚的オブジェクトの役割

Visual クラスは、すべての FrameworkElement オブジェクトの派生元となる基本的な抽象化です。 また、WPF で新しいコントロールを記述するためのエントリ ポイントとしても機能し、多くの点で Win32 アプリケーション モデルのウィンドウ ハンドル (HWND) と考えることができます。

Visual オブジェクトは主要な WPF オブジェクトであり、その主な役割はレンダリングのサポートを提供することです。 ButtonTextBoxなどのユーザー インターフェイス コントロールは、Visual クラスから派生し、レンダリング データの永続化に使用します。 Visual オブジェクトは、次のサポートを提供します。

  • 出力表示: ビジュアルの永続化されたシリアル化された描画コンテンツをレンダリングします。

  • 変換: ビジュアルに対して変換を実行します。

  • クリッピング: ビジュアルのクリッピング領域をサポートします。

  • ヒット テスト: 座標またはジオメトリがビジュアルの境界内に含まれているかどうかを判断します。

  • 境界ボックスの計算: ビジュアルの四角形領域を決定します。

ただし、Visual オブジェクトには、次のような非レンダリング機能のサポートは含まれていません。

  • イベント処理

  • レイアウト

  • スタイル

  • データ バインディング

  • グローバリゼーション

Visual は、子クラスを派生させる必要があるパブリック抽象クラスとして公開されます。 次の図は、WPF で公開されているビジュアル オブジェクトの階層を示しています。

Visual オブジェクト から派生したクラスの図

DrawingVisual クラス

DrawingVisual は、図形、画像、またはテキストをレンダリングするために使用される軽量の描画クラスです。 このクラスは、レイアウトやイベント処理を提供しないため、軽量と見なされ、実行時のパフォーマンスが向上します。 このため、描画は背景やクリップ アートに最適です。 DrawingVisual を使用して、カスタム ビジュアル オブジェクトを作成できます。 詳細については、DrawingVisual オブジェクトの使用を参照してください。

Viewport3DVisual クラス

Viewport3DVisual は、2D VisualVisual3D オブジェクトの間のブリッジを提供します。 Visual3D クラスは、すべての 3D ビジュアル要素の基本クラスです。 Viewport3DVisual では、Camera 値と Viewport 値を定義する必要があります。 カメラを使用すると、シーンを表示できます。 ビューポートは、プロジェクションが 2D サーフェスにマップされる場所を確立します。 WPF での 3D の詳細については、「3D Graphics Overview」を参照してください。

ContainerVisual クラス

ContainerVisual クラスは、Visual オブジェクトのコレクションのコンテナーとして使用されます。 DrawingVisual クラスは、ContainerVisual クラスから派生し、ビジュアル オブジェクトのコレクションを格納できます。

ビジュアル オブジェクトでのコンテンツの描画

Visual オブジェクトは、レンダリング データを ベクター グラフィックス命令リストとして格納します。 命令リストの各項目は、低レベルのグラフィックス データと関連リソースのセットをシリアル化された形式で表します。 描画コンテンツを含めることができるレンダリング データには、4 種類があります。

描画コンテンツ タイプ 説明
ベクター グラフィックス ベクター グラフィックス データ、および関連する Brush および Pen 情報を表します。
画像 Rectによって定義された領域内のイメージを表します。
グリフ 指定したフォント リソースからのグリフのシーケンスである GlyphRunをレンダリングする図面を表します。 テキストの表現方法は次のようになります。
ビデオ ビデオをレンダリングする図面を表します。

DrawingContext を使用すると、Visual にビジュアル コンテンツを設定できます。 DrawingContext オブジェクトの描画コマンドを使用する場合は、実際には、後でグラフィックス システムで使用される一連のレンダリング データを格納します。リアルタイムで画面に描画されません。

Buttonなどの WPF コントロールを作成すると、コントロールは描画自体のレンダリング データを暗黙的に生成します。 たとえば、ButtonContent プロパティを設定すると、コントロールはグリフのレンダリング表現を格納します。

Visual は、そのコンテンツを、DrawingGroup内に含まれる 1 つ以上の Drawing オブジェクトとして記述します。 DrawingGroup では、不透明度マスク、変換、ビットマップ効果、およびそのコンテンツに適用されるその他の操作についても説明します。 DrawingGroup 操作は、コンテンツがレンダリングされるときに、OpacityMaskOpacityBitmapEffectClipGeometryGuidelineSetTransformの順に適用されます。

次の図は、レンダリング シーケンス中に DrawingGroup 操作が適用される順序を示しています。

DrawingGroup の操作の順序 に設定する
DrawingGroup 操作の順序

詳細については、「図面オブジェクトの概要」を参照してください。

ビジュアル レイヤーでのコンテンツの描画

DrawingContextを直接インスタンス化することはありません。ただし、DrawingGroup.OpenDrawingVisual.RenderOpenなど、特定のメソッドから描画コンテキストを取得できます。 次の例では、DrawingVisual から DrawingContext を取得し、それを使用して四角形を描画します。

// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle()
{
    DrawingVisual drawingVisual = new DrawingVisual();

    // Retrieve the DrawingContext in order to create new drawing content.
    DrawingContext drawingContext = drawingVisual.RenderOpen();

    // Create a rectangle and draw it in the DrawingContext.
    Rect rect = new Rect(new System.Windows.Point(160, 100), new System.Windows.Size(320, 80));
    drawingContext.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);

    // Persist the drawing content.
    drawingContext.Close();

    return drawingVisual;
}
' Create a DrawingVisual that contains a rectangle.
Private Function CreateDrawingVisualRectangle() As DrawingVisual
    Dim drawingVisual As New DrawingVisual()

    ' Retrieve the DrawingContext in order to create new drawing content.
    Dim drawingContext As DrawingContext = drawingVisual.RenderOpen()

    ' Create a rectangle and draw it in the DrawingContext.
    Dim rect As New Rect(New Point(160, 100), New Size(320, 80))
    drawingContext.DrawRectangle(Brushes.LightBlue, CType(Nothing, Pen), rect)

    ' Persist the drawing content.
    drawingContext.Close()

    Return drawingVisual
End Function

ビジュアル レイヤーでの描画コンテンツの列挙

その他の用途に加えて、Drawing オブジェクトには、Visualの内容を列挙するためのオブジェクト モデルも用意されています。

手記

ビジュアルの内容を列挙するときは、ベクター グラフィックス命令リストとしてレンダリング データの基になる表現ではなく、Drawing オブジェクトを取得します。

次の例では、GetDrawing メソッドを使用して、VisualDrawingGroup 値を取得して列挙します。

public void RetrieveDrawing(Visual v)
{
    DrawingGroup drawingGroup = VisualTreeHelper.GetDrawing(v);
    EnumDrawingGroup(drawingGroup);
}

// Enumerate the drawings in the DrawingGroup.
public void EnumDrawingGroup(DrawingGroup drawingGroup)
{
    DrawingCollection dc = drawingGroup.Children;

    // Enumerate the drawings in the DrawingCollection.
    foreach (Drawing drawing in dc)
    {
        // If the drawing is a DrawingGroup, call the function recursively.
        if (drawing is DrawingGroup group)
        {
            EnumDrawingGroup(group);
        }
        else if (drawing is GeometryDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is ImageDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is GlyphRunDrawing)
        {
            // Perform action based on drawing type.
        }
        else if (drawing is VideoDrawing)
        {
            // Perform action based on drawing type.
        }
    }
}

ビジュアル オブジェクトを使用してコントロールを構築する方法

WPF のオブジェクトの多くは、他のビジュアル オブジェクトで構成されています。つまり、子孫オブジェクトのさまざまな階層を含めることができます。 コントロールなど、WPF のユーザー インターフェイス要素の多くは、さまざまな種類のレンダリング要素を表す複数のビジュアル オブジェクトで構成されています。 たとえば、Button コントロールには、ClassicBorderDecoratorContentPresenterTextBlockなど、他の多数のオブジェクトを含めることができます。

次のコードは、マークアップで定義された Button コントロールを示しています。

<Button Click="OnClick">OK</Button>

既定の Button コントロールを構成するビジュアル オブジェクトを列挙すると、次に示すビジュアル オブジェクトの階層が見つかります。

ビジュアル ツリー階層の の図

Button コントロールには ClassicBorderDecorator エレメントが含まれており、そのエレメントには ContentPresenter エレメントが含まれています。 ClassicBorderDecorator 要素は、Buttonの境界線と背景を描画します。 ContentPresenter 要素は、Buttonの内容を表示します。 この場合、テキストを表示しているため、ContentPresenter 要素には TextBlock 要素が含まれます。 Button コントロールが ContentPresenter を使用するという事実は、コンテンツが Image やジオメトリ (EllipseGeometryなど) などの他の要素によって表される可能性があることを意味します。

コントロール テンプレート

コントロールの階層へのコントロールの拡張の鍵は、ControlTemplateです。 コントロール テンプレートは、コントロールの既定のビジュアル階層を指定します。 コントロールを明示的に参照すると、そのビジュアル階層が暗黙的に参照されます。 コントロール テンプレートの既定値をオーバーライドして、コントロールのカスタマイズされた外観を作成できます。 たとえば、Button コントロールの背景色の値を変更して、単色の値ではなく線形グラデーションの色の値を使用するようにすることができます。 詳細については、「ボタンのスタイルとテンプレートの」を参照してください。

Button コントロールなどのユーザー インターフェイス要素には、コントロールのレンダリング定義全体を記述するベクター グラフィックス命令リストがいくつか含まれています。 次のコードは、マークアップで定義された Button コントロールを示しています。

<Button Click="OnClick">
  <Image Source="images\greenlight.jpg"></Image>
</Button>

Button コントロールを構成するビジュアル オブジェクトとベクター グラフィックス命令リストを列挙すると、次に示すオブジェクトの階層が見つかります。

ビジュアル ツリーとレンダリング データ の図

Button コントロールには ClassicBorderDecorator 要素が含まれ、次の要素には ContentPresenter 要素が含まれます。 ClassicBorderDecorator 要素は、ボタンの境界線と背景を構成するすべての個別のグラフィック要素を描画します。 ContentPresenter 要素は、Buttonの内容を表示します。 この場合、画像を表示しているため、ContentPresenter 要素には Image 要素が含まれます。

ビジュアル オブジェクトとベクター グラフィックス命令リストの階層については、次の点に注意してください。

  • 階層内の順序は、描画情報のレンダリング順序を表します。 子要素は、ルート ビジュアル要素を起点として、左から右、上から下に走査されます。 要素に視覚的な子要素がある場合、それらの子要素は要素自身の兄弟要素よりも先に走査されます。

  • ContentPresenterなどの階層内の非リーフ ノード要素は、子要素を含めるために使用されます。命令リストは含まれません。

  • ビジュアル要素にベクター グラフィックス命令リストとビジュアル子の両方が含まれている場合、親ビジュアル要素の命令リストは、いずれかのビジュアル子オブジェクト内の描画の前にレンダリングされます。

  • ベクター グラフィックス命令リスト内の項目は、左から右にレンダリングされます。

ビジュアル ツリー

ビジュアル ツリーには、アプリケーションのユーザー インターフェイスで使用されるすべてのビジュアル要素が含まれています。 ビジュアル要素には永続化された描画情報が含まれるため、ビジュアル ツリーはシーン グラフと考えることができます。このグラフには、ディスプレイ デバイスへの出力を構成するために必要なすべてのレンダリング情報が含まれます。 このツリーは、コードでもマークアップでも、アプリケーションによって直接作成されたすべてのビジュアル要素の蓄積です。 ビジュアル ツリーには、コントロールやデータ オブジェクトなどの要素のテンプレート拡張によって作成されたすべてのビジュアル要素も含まれます。

次のコードは、マークアップで定義された StackPanel 要素を示しています。

<StackPanel>
  <Label>User name:</Label>
  <TextBox />
  <Button Click="OnClick">OK</Button>
</StackPanel>

マークアップの例で StackPanel 要素を構成するビジュアル オブジェクトを列挙すると、次に示すビジュアル オブジェクトの階層が見つかります。

StackPanel コントロールのビジュアル ツリー階層の図。

レンダリング順序

ビジュアル ツリーは、WPF ビジュアル オブジェクトと描画オブジェクトのレンダリング順序を決定します。 トラバーサルの順序は、ルート ビジュアル (ビジュアル ツリーの最上位ノード) から始まります。 次に、ルート ビジュアルの子が左から右に走査されます。 ビジュアルの子が存在する場合、子はビジュアルの兄弟よりも先に走査されます。 つまり、子ビジュアルのコンテンツは、ビジュアル自体のコンテンツの前にレンダリングされます。

ビジュアル ツリーのレンダリング順序 の図

ルート ビジュアル

ルート ビジュアル は、ビジュアル ツリー階層の最上位の要素です。 ほとんどのアプリケーションでは、ルート ビジュアルの基本クラスは Window または NavigationWindowです。 ただし、Win32 アプリケーションでビジュアル オブジェクトをホストしていた場合、ルート ビジュアルは Win32 ウィンドウでホストしていた最も多くのビジュアルになります。 詳細については、「チュートリアル: Win32 アプリケーションでのビジュアル オブジェクトのホスト」を参照してください。

論理ツリーとの関係

WPF の論理ツリーは、実行時にアプリケーションの要素を表します。 このツリーは直接操作しませんが、アプリケーションのこのビューは、プロパティの継承とイベント ルーティングを理解するのに役立ちます。 ビジュアル ツリーとは異なり、論理ツリーは、ListItemなどの非ビジュアル データ オブジェクトを表すことができます。 多くの場合、論理ツリーはアプリケーションのマークアップ定義に非常に密接にマップされます。 次のコードは、マークアップで定義された DockPanel 要素を示しています。

<DockPanel>
  <ListBox>
    <ListBoxItem>Dog</ListBoxItem>
    <ListBoxItem>Cat</ListBoxItem>
    <ListBoxItem>Fish</ListBoxItem>
  </ListBox>
  <Button Click="OnClick">OK</Button>
</DockPanel>

マークアップの例で DockPanel 要素を構成する論理オブジェクトを列挙すると、次に示す論理オブジェクトの階層が見つかります。

ツリー図
論理ツリーの図

ビジュアル ツリーと論理ツリーの両方が、要素の追加、削除、または変更を反映して、現在のアプリケーション要素のセットと同期されます。 ただし、ツリーにはアプリケーションのさまざまなビューが表示されます。 ビジュアル ツリーとは異なり、論理ツリーはコントロールの ContentPresenter 要素を展開しません。 つまり、同じオブジェクト セットに対して論理ツリーとビジュアル ツリーの間に直接的な 1 対 1 の対応は存在しません。 実際、LogicalTreeHelper オブジェクトの GetChildren メソッドを呼び出すと、VisualTreeHelper 同じ要素をパラメーターとして使用してオブジェクトの GetChild メソッドが生成され、異なる結果が得られます。

論理ツリーの詳細については、「WPFの ツリー」を参照してください。

XamlPad を使用したビジュアル ツリーの表示

WPF ツールの XamlPad には、現在定義されている XAML コンテンツに対応するビジュアル ツリーを表示および探索するためのオプションが用意されています。 メニュー バーの [ビジュアル ツリーの表示] ボタンをクリックして、ビジュアル ツリーを表示します。 次に、XamlPad の Visual Tree Explorer パネルで XAML コンテンツをビジュアル ツリー ノードに展開する方法を示します。

XamlPad の [Visual Tree Explorer] パネルを する

LabelTextBox、および Button コントロールが XamlPad の Visual Tree Explorer パネルに個別のビジュアル オブジェクト階層を表示する方法に注目してください。 これは、WPF コントロールには、そのコントロールのビジュアル ツリーを含む ControlTemplate があるためです。 コントロールを明示的に参照すると、そのビジュアル階層が暗黙的に参照されます。

ビジュアル パフォーマンスのプロファイリング

WPF には、アプリケーションの実行時の動作を分析し、適用できるパフォーマンス最適化の種類を決定できるパフォーマンス プロファイリング ツールのスイートが用意されています。 Visual Profiler ツールは、アプリケーションのビジュアル ツリーに直接マッピングすることで、パフォーマンス データの豊富なグラフィカル ビューを提供します。 このスクリーンショットでは、Visual Profiler の CPU 使用率 セクションに、レンダリングやレイアウトなど、オブジェクトによる WPF サービスの使用の詳細が示されています。

Visual Profiler Visual Profiler 表示出力 に表示する
Visual Profiler の表示出力

ビジュアル レンダリングの動作

WPF には、保持モード のグラフィックス、ベクター グラフィックス、デバイスに依存しないグラフィックスなど、ビジュアル オブジェクトのレンダリング動作に影響するいくつかの機能が導入されています。

保持モードのグラフィックス

Visual オブジェクトの役割を理解する鍵の 1 つは、イミディエイト モード保持モード グラフィックス システムの違いを理解することです。 GDI または GDI+ に基づく標準的な Win32 アプリケーションでは、イミディエイト モードのグラフィックス システムを使用します。 つまり、ウィンドウのサイズ変更やオブジェクトの外観の変更などのアクションが原因で、無効にされたクライアント領域の部分をアプリケーションが再描画する必要があります。

Win32 レンダリング シーケンス の図

これに対し、WPF は保持モード システムを使用します。 つまり、視覚的な外観を持つアプリケーション オブジェクトは、一連のシリアル化された描画データを定義します。 描画データが定義されると、システムはその後、アプリケーション オブジェクトをレンダリングするためのすべての再描画要求に応答する必要があります。 実行時でも、アプリケーション オブジェクトを変更または作成でき、描画要求に応答するためにシステムに依存できます。 保持モードのグラフィックス システムでは、描画情報は常にアプリケーションによってシリアル化された状態で保持されますが、レンダリングの責任はシステムに委ねられます。 次の図は、アプリケーションが WPF を使用して描画要求に応答する方法を示しています。

WPF レンダリング シーケンス の図

インテリジェントな再描画

保持モードグラフィックスを使用する最大の利点の 1 つは、WPF がアプリケーションで再描画する必要のあるものを効率的に最適化できることです。 不透明度のレベルが異なる複雑なシーンがある場合でも、通常、再描画を最適化するために特別な目的のコードを記述する必要はありません。 これを Win32 プログラミングと比較すると、更新リージョンでの再描画の量を最小限に抑えることで、アプリケーションの最適化に多大な労力を費やすことができます。 Win32アプリケーションにおける再描画の最適化に関連する複雑さの例については、「更新領域 の再描画 」を参照してください。

ベクター グラフィックス

WPF では、レンダリング データ形式として ベクター グラフィックス が使用されます。 スケーラブル ベクター グラフィックス (SVG)、Windows メタファイル (.wmf)、および TrueType フォントを含むベクター グラフィックスは、レンダリング データを格納し、グラフィックス プリミティブを使用してイメージを再作成する方法を説明する手順の一覧として送信します。 たとえば、TrueType フォントは、ピクセル配列ではなく、線、曲線、およびコマンドのセットを記述するアウトライン フォントです。 ベクター グラフィックスの主な利点の 1 つは、任意のサイズと解像度にスケーリングできることです。

ベクター グラフィックスとは異なり、ビットマップ グラフィックスでは、レンダリング データがイメージのピクセル単位の表現として格納され、特定の解像度で事前にレンダリングされます。 ビットマップ グラフィック形式とベクター グラフィック形式の主な違いの 1 つは、元のソース イメージに対する忠実性です。 たとえば、ソース イメージのサイズが変更されると、ビットマップ グラフィックス システムはイメージを拡大し、ベクター グラフィックス システムはイメージを拡大縮小し、イメージの忠実性を維持します。

次の図は、ソース イメージが 300% に拡大された場合の例です。 ソース イメージがベクター グラフィックス イメージとして拡大縮小されるのではなく、ビットマップ グラフィックス イメージとしてストレッチされるときに発生する歪みに注目してください。

ラスター グラフィックスとベクター グラフィックスの違い

次のマークアップは、定義された 2 つの Path 要素を示しています。 2 番目の要素は、ScaleTransform を使用して、最初の要素の描画命令のサイズを 300%変更します。 Path 要素の描画命令は変更されていないことに注意してください。

<Path
  Data="M10,100 C 60,0 100,200 150,100 z"
  Fill="{StaticResource linearGradientBackground}"
  Stroke="Black"
  StrokeThickness="2" />

<Path
  Data="M10,100 C 60,0 100,200 150,100 z"
  Fill="{StaticResource linearGradientBackground}"
  Stroke="Black"
  StrokeThickness="2" >
  <Path.RenderTransform>
    <ScaleTransform ScaleX="3.0" ScaleY="3.0" />
  </Path.RenderTransform>
</Path>

解像度と Device-Independent グラフィックスについて

画面のテキストとグラフィックスのサイズを決定する 2 つのシステム 要素があります。解像度と DPI です。 解像度は、画面に表示されるピクセル数を表します。 解像度が高くなるにつれてピクセルが小さくなり、グラフィックスとテキストが小さく表示されます。 解像度を 1600 x 1200 に変更すると、1024 x 768 に設定されたモニターに表示されるグラフィックが大幅に小さく表示されます。

もう 1 つのシステム設定 DPI は、画面インチのサイズをピクセル単位で表します。 ほとんどの Windows システムの DPI は 96 です。つまり、画面インチは 96 ピクセルです。 DPI 設定を大きくすると、画面インチが大きくなります。DPI を下げると、画面インチが小さくなります。 つまり、画面インチは実際のインチと同じサイズではありません。ほとんどのシステムでは、それはおそらくありません。 DPI を増やすと、画面インチのサイズが大きくなったため、DPI 対応のグラフィックスとテキストが大きくなります。 DPI を大きくすると、特に高解像度でテキストを読みやすくすることができます。

すべてのアプリケーションが DPI に対応しているわけではありません。一部のアプリケーションでは、主要な測定単位としてハードウェア ピクセルを使用します。システム DPI を変更しても、これらのアプリケーションには影響しません。 他の多くのアプリケーションでは、DPI 対応の単位を使用してフォント サイズを記述しますが、ピクセルを使用して他のすべてを記述します。 DPI を小さすぎるか大きすぎると、これらのアプリケーションのレイアウトの問題が発生する可能性があります。これは、アプリケーションのテキストがシステムの DPI 設定でスケーリングされますが、アプリケーションの UI ではスケーリングされないためです。 この問題は、WPF を使用して開発されたアプリケーションで解消されました。

WPF では、ハードウェア ピクセルではなく、デバイスに依存しないピクセルを主要な測定単位として使用することで、自動スケーリングがサポートされます。グラフィックとテキストは、アプリケーション開発者の余分な作業なしで適切にスケーリングできます。 次の図は、WPF のテキストとグラフィックスがさまざまな DPI 設定でどのように表示されるかの例を示しています。

さまざまな DPI 設定でのグラフィックスとテキストの例
さまざまな DPI 設定でのグラフィックスとテキスト

VisualTreeHelper クラス

VisualTreeHelper クラスは、ビジュアル オブジェクト レベルでプログラミングするための低レベルの機能を提供する静的ヘルパー クラスです。これは、高パフォーマンスのカスタム コントロールの開発など、非常に具体的なシナリオで役立ちます。 ほとんどの場合、CanvasTextBlockなどの上位レベルの WPF フレームワーク オブジェクトは、より高い柔軟性と使いやすさを提供します。

ヒット テスト

VisualTreeHelper クラスは、既定のヒット テストのサポートがニーズを満たしていない場合に、ビジュアル オブジェクトでヒット テストを行うメソッドを提供します。 VisualTreeHelper クラスの HitTest メソッドを使用して、ジオメトリまたはポイント座標値がコントロールやグラフィック要素などの特定のオブジェクトの境界内にあるかどうかを判断できます。 たとえば、ヒット テストを使用して、オブジェクトの外接する四角形内のマウス クリックが円のジオメトリ内にあるかどうかを判断できます。また、ヒット テストの既定の実装をオーバーライドして、独自のカスタム ヒット テスト計算を実行することもできます。

ヒット テストの詳細については、「ビジュアル レイヤーでのヒット テストの 」を参照してください。

ビジュアル ツリーを列挙する

VisualTreeHelper クラスは、ビジュアル ツリーのメンバーを列挙するための機能を提供します。 親を取得するには、GetParent メソッドを呼び出します。 ビジュアル オブジェクトの子 (直接子孫) を取得するには、GetChild メソッドを呼び出します。 このメソッドは、指定したインデックス位置にある親の子 Visual を返します。

次の例は、ビジュアル オブジェクトのすべての子孫を列挙する方法を示しています。これは、ビジュアル オブジェクト階層のすべてのレンダリング情報をシリアル化する場合に使用する手法です。

// Enumerate all the descendants of the visual object.
static public void EnumVisual(Visual myVisual)
{
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i++)
    {
        // Retrieve child visual at specified index value.
        Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i);

        // Do processing of the child visual object.

        // Enumerate children of the child visual object.
        EnumVisual(childVisual);
    }
}
' Enumerate all the descendants of the visual object.
Public Shared Sub EnumVisual(ByVal myVisual As Visual)
    For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(myVisual) - 1
        ' Retrieve child visual at specified index value.
        Dim childVisual As Visual = CType(VisualTreeHelper.GetChild(myVisual, i), Visual)

        ' Do processing of the child visual object.

        ' Enumerate children of the child visual object.
        EnumVisual(childVisual)
    Next i
End Sub

ほとんどの場合、論理ツリーは WPF アプリケーションの要素のより便利な表現です。 論理ツリーを直接変更することはありませんが、アプリケーションのこのビューは、プロパティの継承とイベント ルーティングを理解するのに役立ちます。 ビジュアル ツリーとは異なり、論理ツリーは、ListItemなどの非ビジュアル データ オブジェクトを表すことができます。 論理ツリーの詳細については、「WPFの ツリー」を参照してください。

VisualTreeHelper クラスは、ビジュアル オブジェクトの境界矩形を返すメソッドを提供します。 GetContentBoundsを呼び出すと、ビジュアルオブジェクトの外接矩形を取得できます。 GetDescendantBounds を呼び出すと、ビジュアル オブジェクトのすべての子孫 (ビジュアル オブジェクト自体も含む) の四角形領域が返されます。 次のコードは、ビジュアルオブジェクトとそのすべての子孫の外接矩形を計算する方法を示しています。

// Return the bounding rectangle of the parent visual object and all of its descendants.
Rect rectBounds = VisualTreeHelper.GetDescendantBounds(parentVisual);
' Return the bounding rectangle of the parent visual object and all of its descendants.
Dim rectBounds As Rect = VisualTreeHelper.GetDescendantBounds(parentVisual)

関連項目