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

ここでは、WPFWPF のビジュアル層の概要について説明します。This topic provides an overview of the WPFWPF visual layer. この記事では、WPFWPF モデルでレンダリングをサポートするための Visual クラスの役割に焦点を当てています。It focuses on the role of the Visual class for rendering support in the WPFWPF model.

ビジュアル オブジェクトの役割Role of the Visual Object

@No__t-0 クラスは、すべての FrameworkElement オブジェクトが派生する基本抽象化です。The Visual class is the basic abstraction from which every FrameworkElement object derives. また、このクラスは、WPFWPF で新しいコントロールを作成するためのエントリ ポイントとしても機能し、多くの点で Win32 アプリケーション モデルのウィンドウ ハンドル (HWND) と考えることができます。It also serves as the entry point for writing new controls in WPFWPF, and in many ways can be thought of as the window handle (HWND) in the Win32 application model.

@No__t 0 オブジェクトは主要な WPFWPF オブジェクトであり、プライマリロールがレンダリングサポートを提供します。The Visual object is a core WPFWPF object, whose primary role is to provide rendering support. @No__t-0 や TextBox などのユーザーインターフェイスコントロールは、Visual クラスから派生し、レンダリングデータを保持するために使用します。User interface controls, such as Button and TextBox, derive from the Visual class, and use it for persisting their rendering data. @No__t 0 オブジェクトでは、次の機能がサポートされています。The Visual object provides support for:

  • 出力の表示:ビジュアルの永続化された、シリアル化された描画コンテンツをレンダリングしています。Output display: Rendering the persisted, serialized drawing content of a visual.

  • 転換ビジュアルで変換を実行する。Transformations: Performing transformations on a visual.

  • クリッピングビジュアルのクリッピング領域のサポートを提供します。Clipping: Providing clipping region support for a visual.

  • ヒットテスト:座標またはジオメトリがビジュアルの境界内に含まれるかどうかを判断します。Hit testing: Determining whether a coordinate or geometry is contained within the bounds of a visual.

  • 境界ボックスの計算:ビジュアルの外接する四角形を決定する。Bounding box calculations: Determining the bounding rectangle of a visual.

ただし、@no__t 0 のオブジェクトには、次のような非レンダリング機能のサポートは含まれていません。However, the Visual object does not include support for non-rendering features, such as:

  • イベント処理Event handling

  • レイアウトLayout

  • スタイルStyles

  • データ バインディングData binding

  • グローバリゼーションGlobalization

Visual は、子クラスを派生させる必要があるパブリック抽象クラスとして公開されます。Visual is exposed as a public abstract class from which child classes must be derived. WPFWPF で公開されるビジュアル オブジェクトの階層構造を次の図に示します。The following illustration shows the hierarchy of the visual objects that are exposed in WPFWPF.

Visual オブジェクトから派生したクラスのダイアグラム

DrawingVisual クラスDrawingVisual Class

@No__t-0 は、図形、画像、またはテキストを表示するために使用される軽量の描画クラスです。The DrawingVisual is a lightweight drawing class that is used to render shapes, images, or text. このクラスが軽量と見なされる理由は、レイアウトやイベントの処理を行わないため、実行時のパフォーマンスが向上するからです。This class is considered lightweight because it does not provide layout or event handling, which improves its runtime performance. そのため、背景やクリップ アートの描画に適しています。For this reason, drawings are ideal for backgrounds and clip art. @No__t 0 を使用して、カスタムビジュアルオブジェクトを作成できます。The DrawingVisual can be used to create a custom visual object. 詳しくは、「DrawingVisual オブジェクトの使用」をご覧ください。For more information, see Using DrawingVisual Objects.

Viewport3DVisual クラスViewport3DVisual Class

@No__t-0 は、2D Visual と @no__t 2 つのオブジェクト間のブリッジを提供します。The Viewport3DVisual provides a bridge between 2D Visual and Visual3D objects. @No__t-0 クラスは、すべての3D ビジュアル要素の基本クラスです。The Visual3D class is the base class for all 3D visual elements. @No__t-0 では、@no__t 1 の値と @no__t 2 の値を定義する必要があります。The Viewport3DVisual requires that you define a Camera value and a Viewport value. カメラを使用するとシーンを表示できます。The camera allows you to view the scene. ビューポートは、投影が 2D サーフェイス上にマップされる場所を設定します。The viewport establishes where the projection maps onto the 2D surface. WPFWPF の 3D について詳しくは、「3-D グラフィックスの概要」をご覧ください。For more information on 3D in WPFWPF, see 3-D Graphics Overview.

ContainerVisual クラスContainerVisual Class

@No__t-0 クラスは、Visual オブジェクトのコレクションのコンテナーとして使用されます。The ContainerVisual class is used as a container for a collection of Visual objects. @No__t-0 クラスは、ContainerVisual クラスから派生し、ビジュアルオブジェクトのコレクションを格納できるようにします。The DrawingVisual class derives from the ContainerVisual class, allowing it to contain a collection of visual objects.

ビジュアル オブジェクトの描画コンテンツDrawing Content in Visual Objects

@No__t 0 オブジェクトは、そのレンダリングデータをベクターグラフィックス命令リストとして格納します。A Visual object stores its render data as a vector graphics instruction list. 命令リスト内の各項目は、グラフィックス データと関連リソースの低レベル セットを、シリアル化された形式で表します。Each item in the instruction list represents a low-level set of graphics data and associated resources in a serialized format. 描画コンテンツを格納できるレンダリング データには、次の 4 つの種類があります。There are four different types of render data that can contain drawing content.

描画コンテンツの種類Drawing content type 説明Description
ベクター グラフィックスVector graphics ベクターグラフィックスデータ、および関連付けられている @no__t 0 および Pen の情報を表します。Represents vector graphics data, and any associated Brush and Pen information.
イメージImage @No__t によって定義される領域内のイメージを表します-0。Represents an image within a region defined by a Rect.
グリフGlyph 指定されたフォントリソースからの一連のグリフである @no__t 0 をレンダリングする描画を表します。Represents a drawing that renders a GlyphRun, which is a sequence of glyphs from a specified font resource. テキストはこれによって表示されます。This is how text is represented.
ビデオVideo ビデオをレンダリングする描画を表します。Represents a drawing that renders video.

@No__t-0 を使用すると、@no__t にビジュアルコンテンツを設定できます。The DrawingContext allows you to populate a Visual with visual content. @No__t 0 オブジェクトの描画コマンドを使用する場合、実際には、グラフィックスシステムによって使用されるレンダリングデータのセットを格納します。リアルタイムで画面に描画していません。When you use a DrawingContext object's draw commands, you are actually storing a set of render data that will later be used by the graphics system; you are not drawing to the screen in real-time.

@No__t-1 などの @no__t 0 コントロールを作成すると、コントロールによって描画用のレンダリングデータが暗黙的に生成されます。When you create a WPFWPF control, such as a Button, the control implicitly generates render data for drawing itself. たとえば、ButtonContent プロパティを設定すると、コントロールはグリフのレンダリング表現を格納します。For example, setting the Content property of the Button causes the control to store a rendering representation of a glyph.

@No__t-0 は、DrawingGroup 内に含まれる1つ以上の @no__t 1 オブジェクトとしてそのコンテンツを記述します。A Visual describes its content as one or more Drawing objects contained within a DrawingGroup. @No__t-0 も、不透明マスク、変換、ビットマップ効果、およびその内容に適用されるその他の操作について説明します。A DrawingGroup also describes opacity masks, transforms, bitmap effects, and other operations that are applied to its contents. @no__t 0 の操作は、コンテンツがレンダリングされるときに、OpacityMaskOpacityBitmapEffectClipGeometryGuidelineSetTransform の順に適用されます。DrawingGroup operations are applied in the following order when content is rendered: OpacityMask, Opacity, BitmapEffect, ClipGeometry, GuidelineSet, and then Transform.

次の図は、レンダリングシーケンス中に DrawingGroup 操作が適用される順序を示しています。The following illustration shows the order in which DrawingGroup operations are applied during the rendering sequence.

操作の graphcismm_drawinggroup_order (図面グループの順序 )DrawingGroup order of operations
DrawingGroup の操作の順序Order of DrawingGroup operations

詳しくは、「Drawing オブジェクトの概要」をご覧ください。For more information, see Drawing Objects Overview.

ビジュアル層での描画コンテンツDrawing Content at the Visual Layer

@No__t を直接インスタンス化することはありません-0;ただし、DrawingGroup.OpenDrawingVisual.RenderOpen などの特定のメソッドから描画コンテキストを取得することはできます。You never directly instantiate a DrawingContext; you can, however, acquire a drawing context from certain methods, such as DrawingGroup.Open and DrawingVisual.RenderOpen. 次の例では、DrawingVisual から DrawingContext を取得し、それを使用して四角形を描画します。The following example retrieves a DrawingContext from a DrawingVisual and uses it to draw a rectangle.

// 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

ビジュアル層で描画コンテンツを列挙するEnumerating Drawing Content at the Visual Layer

@No__t-0 オブジェクトは、他の用途に加えて、Visual の内容を列挙するためのオブジェクトモデルも提供します。In addition to their other uses, Drawing objects also provide an object model for enumerating the contents of a Visual.

注意

ビジュアルの内容を列挙する場合、ベクターグラフィックス命令リストとしてレンダリングデータの基になる表現ではなく、@no__t 0 のオブジェクトを取得します。When you are enumerating the contents of the visual, you are retrieving Drawing objects, and not the underlying representation of the render data as a vector graphics instruction list.

次の例では、GetDrawing メソッドを使用して、VisualDrawingGroup 値を取得し、それを列挙します。The following example uses the GetDrawing method to retrieve the DrawingGroup value of a Visual and enumerate it.

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.
        }
    }
}

ビジュアル オブジェクトを使用してコントロールをビルドする方法How Visual Objects are Used to Build Controls

WPFWPF のオブジェクトの多くは、他のビジュアル オブジェクトで構成されています。そのため、それらのオブジェクトには、子孫オブジェクトのさまざまな階層を格納することができます。Many of the objects in WPFWPF are composed of other visual objects, meaning they can contain varying hierarchies of descendant objects. WPFWPF のユーザー インターフェイス要素 (コントロールなど) の多くは、さまざまな種類のレンダリング要素を表す、複数のビジュアル オブジェクトで構成されています。Many of the user interface elements in WPFWPF, such as controls, are composed of multiple visual objects, representing different types of rendering elements. たとえば、@no__t 0 コントロールには、ClassicBorderDecoratorContentPresenterTextBlock など、他の多くのオブジェクトを含めることができます。For example, the Button control can contain a number of other objects, including ClassicBorderDecorator, ContentPresenter, and TextBlock.

次のコードは、マークアップで定義されている @no__t 0 コントロールを示しています。The following code shows a Button control defined in markup.

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

既定の @no__t 0 コントロールを構成するビジュアルオブジェクトを列挙すると、次に示すビジュアルオブジェクトの階層が表示されます。If you were to enumerate the visual objects that comprise the default Button control, you would find the hierarchy of visual objects illustrated below:

ビジュアル ツリー階層のダイアグラム

@No__t 0 コントロールには、1つの @no__t 要素が含まれています。この要素には @no__t 2 つの要素が含まれています。The Button control contains a ClassicBorderDecorator element, which in turn, contains a ContentPresenter element. @No__t-0 要素は、Button の境界線と背景を描画します。The ClassicBorderDecorator element is responsible for drawing a border and a background for the Button. @No__t-0 要素は、Button の内容を表示します。The ContentPresenter element is responsible for displaying the contents of the Button. この場合、テキストを表示しているため、@no__t 0 の要素には、TextBlock の要素が含まれます。In this case, since you are displaying text, the ContentPresenter element contains a TextBlock element. @No__t 0 コントロールが ContentPresenter を使用するということは、Image や @no__t geometry などの他の要素でコンテンツを表すことができることを意味します。The fact that the Button control uses a ContentPresenter means that the content could be represented by other elements, such as an Image or a geometry, such as an EllipseGeometry.

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

コントロールの階層へのコントロールの展開の鍵となるのは、ControlTemplate です。The key to the expansion of a control into a hierarchy of controls is the ControlTemplate. コントロール テンプレートは、コントロールの既定のビジュアル階層を指定します。A control template specifies the default visual hierarchy for a control. コントロールを明示的に参照すると、コントロールのビジュアル階層が暗黙的に参照されます。When you explicitly reference a control, you implicitly reference its visual hierarchy. コントロール テンプレートの既定値をオーバーライドして、コントロールの外観をカスタマイズすることもできます。You can override the default values for a control template to create a customized visual appearance for a control. たとえば、Button コントロールの背景色の値を変更して、純色の値の代わりに線状グラデーションの色の値を使用することができます。For example, you could modify the background color value of the Button control so that it uses a linear gradient color value instead of a solid color value. 詳しくは、「ボタンのスタイルとテンプレート」をご覧ください。For more information, see Button Styles and Templates.

@No__t 0 コントロールなどのユーザーインターフェイス要素には、コントロールのレンダリング定義全体を記述するいくつかのベクターグラフィックス命令リストが含まれています。A user interface element, such as a Button control, contains several vector graphics instruction lists that describe the entire rendering definition of a control. 次のコードは、マークアップで定義されている @no__t 0 コントロールを示しています。The following code shows a Button control defined in markup.

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

@No__t 0 コントロールを構成するビジュアルオブジェクトとベクターグラフィックス命令リストを列挙すると、次の図に示すようなオブジェクトの階層が表示されます。If you were to enumerate the visual objects and vector graphics instruction lists that comprise the Button control, you would find the hierarchy of objects illustrated below:

ビジュアル ツリーおよび描画データのダイアグラム

@No__t 0 コントロールには、1つの @no__t 要素が含まれています。この要素には @no__t 2 つの要素が含まれています。The Button control contains a ClassicBorderDecorator element, which in turn, contains a ContentPresenter element. @No__t 0 要素は、ボタンの境界線と背景を構成するすべての不連続グラフィック要素を描画する役割を担います。The ClassicBorderDecorator element is responsible for drawing all the discrete graphic elements that make up the border and background of a button. @No__t-0 要素は、Button の内容を表示します。The ContentPresenter element is responsible for displaying the contents of the Button. この場合、イメージを表示しているため、@no__t 0 の要素には、@no__t 1 要素が含まれています。In this case, since you are displaying an image, the ContentPresenter element contains a Image element.

ビジュアル オブジェクトとベクター グラフィックス命令リストの階層については、次の点に注意する必要があります。There are a number of points to note about the hierarchy of visual objects and vector graphics instruction lists:

  • 階層内の順序は、描画情報のレンダリング順序を表します。The ordering in the hierarchy represents the rendering order of the drawing information. 子要素は、ルート ビジュアル要素を起点として、左から右、上から下に走査されます。From the root visual element, child elements are traversed, left to right, top to bottom. 要素に子ビジュアル要素がある場合、子ビジュアル要素は要素の兄弟よりも先に走査されます。If an element has visual child elements, they are traversed before the element’s siblings.

  • 階層内の非リーフノード要素 (ContentPresenter など) は、子要素を格納するために使用されます。これには命令リストは含まれません。Non-leaf node elements in the hierarchy, such as ContentPresenter, are used to contain child elements—they do not contain instruction lists.

  • ビジュアル要素にベクター グラフィックス命令リストとビジュアル子の両方が含まれている場合は、ビジュアル子オブジェクトが描画される前に、親ビジュアル要素の命令リストがレンダリングされます。If a visual element contains both a vector graphics instruction list and visual children, the instruction list in the parent visual element is rendered before drawings in any of the visual child objects.

  • ベクター グラフィックス命令リスト内の項目は、左から右の順にレンダリングされます。The items in the vector graphics instruction list are rendered left to right.

ビジュアル ツリーVisual Tree

ビジュアル ツリーには、アプリケーションのユーザー インターフェイスで使用されるすべてのビジュアル要素が含まれます。The visual tree contains all visual elements used in an application's user interface. ビジュアル要素には永続化された描画情報が含まれているので、ビジュアル ツリーは、ディスプレイ デバイスへの出力を構成するのに必要なレンダリング情報をすべて含んだ、シーン グラフであると考えることができます。Since a visual element contains persisted drawing information, you can think of the visual tree as a scene graph, containing all the rendering information needed to compose the output to the display device. このツリーは、コードかマークアップかを問わず、アプリケーションで直接作成されたすべてのビジュアル要素を累積したものです。This tree is the accumulation of all visual elements created directly by the application, whether in code or in markup. ビジュアル ツリーには、コントロールやデータ オブジェクトなど、要素のテンプレート拡張によって作成されたビジュアル要素もすべて含まれます。The visual tree also contains all visual elements created by the template expansion of elements such as controls and data objects.

次のコードは、マークアップで定義されている @no__t 0 要素を示しています。The following code shows a StackPanel element defined in markup.

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

マークアップの例で @no__t 0 要素を構成するビジュアルオブジェクトを列挙すると、次の図に示すようなビジュアルオブジェクトの階層が表示されます。If you were to enumerate the visual objects that comprise the StackPanel element in the markup example, you would find the hierarchy of visual objects illustrated below:

ビジュアル ツリー階層のダイアグラム

レンダリング順序Rendering Order

ビジュアル ツリーは、WPFWPF のビジュアル オブジェクトと描画オブジェクトの表示順序を決定します。The visual tree determines the rendering order of WPFWPF visual and drawing objects. 走査の順序は、ビジュアル ツリーの最上位ノードであるルート ビジュアルから始まります。The order of traversal starts with the root visual, which is the top-most node in the visual tree. 次に、ルート ビジュアルの子が左から右に走査されます。The root visual’s children are then traversed, left to right. ビジュアルの子が存在する場合、子はビジュアルの兄弟よりも先に走査されます。If a visual has children, its children are traversed before the visual’s siblings. つまり、子ビジュアルの内容は、そのビジュアル自体の内容よりも前面に表示されます。This means that the content of a child visual is rendered in front of the visual's own content.

ビジュアルツリーの描画順序のダイアグラム

ルート ビジュアルRoot Visual

ルート ビジュアルは、ビジュアル ツリー階層内の最上位の要素です。The root visual is the top-most element in a visual tree hierarchy. ほとんどのアプリケーションでは、ルートビジュアルの基底クラスは Window または NavigationWindow のいずれかです。In most applications, the base class of the root visual is either Window or NavigationWindow. ただし、ビジュアル オブジェクトを Win32 アプリケーションでホストする場合は、Win32 ウィンドウにホストする最上位のビジュアルがルート ビジュアルになります。However, if you were hosting visual objects in a Win32 application, the root visual would be the top-most visual you were hosting in the Win32 window. 詳しくは、「[チュートリアル: Win32 アプリケーションでのビジュアルオブジェクトのホスト @ no__t-0。For more information, see Tutorial: Hosting Visual Objects in a Win32 Application.

論理ツリーとの関係Relationship to the Logical Tree

WPFWPF の論理ツリーは、実行時のアプリケーションの要素を表します。The logical tree in WPFWPF represents the elements of an application at run time. このツリーを直接操作することはありませんが、アプリケーションのこのビューは、プロパティの継承やイベントのルーティングを理解する上で役立ちます。Although you do not manipulate this tree directly, this view of the application is useful for understanding property inheritance and event routing. ビジュアルツリーとは異なり、論理ツリーは、ListItem などの非ビジュアルデータオブジェクトを表すことができます。Unlike the visual tree, the logical tree can represent non-visual data objects, such as ListItem. 多くの場合、論理ツリーはアプリケーションのマークアップ定義にほぼ一致します。In many cases, the logical tree maps very closely to an application's markup definitions. 次のコードは、マークアップで定義されている @no__t 0 要素を示しています。The following code shows a DockPanel element defined in markup.

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

マークアップの例で @no__t 0 要素を構成する論理オブジェクトを列挙すると、次の図に示すような論理オブジェクトの階層が表示されます。If you were to enumerate the logical objects that comprise the DockPanel element in the markup example, you would find the hierarchy of logical objects illustrated below:

ツリーダイアグラムTree diagram
論理ツリーのダイアグラムDiagram of logical tree

ビジュアル ツリーと論理ツリーはどちらも、現在のアプリケーション要素セットと同期し、要素の追加、削除、または変更をすべて反映します。Both the visual tree and logical tree are synchronized with the current set of application elements, reflecting any addition, deletion, or modification of elements. ただし、これらのツリーが表すアプリケーションのビューはそれぞれ異なるものです。However, the trees present different views of the application. ビジュアルツリーとは異なり、論理ツリーはコントロールの @no__t 0 要素を展開しません。Unlike the visual tree, the logical tree does not expand a control's ContentPresenter element. つまり、同じオブジェクト セットについて見ても、論理ツリーとビジュアルツリーの間に 1 対 1 の対応関係はありません。This means there is not a direct one-to-one correspondence between a logical tree and a visual tree for the same set of objects. 実際、 Logicaltreehelperオブジェクトの GetChildren メソッドと、パラメーターと同じ要素を使用したVisualTreeHelperオブジェクトの @no__t メソッドを呼び出すと、結果は異なります。In fact, invoking the LogicalTreeHelper object's GetChildren method and the VisualTreeHelper object's GetChild method using the same element as a parameter yields differing results.

論理ツリーについて詳しくは、「WPF のツリー」をご覧ください。For more information on the logical tree, see Trees in WPF.

XamlPad を使用したビジュアル ツリーの表示Viewing the Visual Tree with XamlPad

@No__t 0 ツール XamlPad は、現在定義されている XAML コンテンツに対応するビジュアルツリーを表示および探索するためのオプションを提供します。The WPFWPF tool, XamlPad, provides an option for viewing and exploring the visual tree that corresponds to the currently defined XAML content. ビジュアル ツリーを表示するには、メニュー バーの [Show Visual Tree] (ビジュアル ツリーを表示) ボタンをクリックします。Click the Show Visual Tree button on the menu bar to display the visual tree. 次に示すのは、XamlPad のビジュアルツリーエクスプローラーパネルで、ビジュアルツリーノードに XAML コンテンツを展開する方法を示しています。The following illustrates the expansion of XAML content into visual tree nodes in the Visual Tree Explorer panel of XamlPad:

XamlPad のビジュアル ツリー エクスプローラー パネル

@No__t-0、TextBox、および Button コントロールが、XamlPad のビジュアルツリーエクスプローラーパネルにそれぞれ個別のビジュアルオブジェクト階層を表示することに注意してください。Notice how the Label, TextBox, and Button controls each display a separate visual object hierarchy in the Visual Tree Explorer panel of XamlPad. これは、WPFWPF コントロールは、そのコントロールのビジュアルツリーを含む ControlTemplate を持つためです。This is because WPFWPF controls have a ControlTemplate that contains the visual tree of that control. コントロールを明示的に参照すると、コントロールのビジュアル階層が暗黙的に参照されます。When you explicitly reference a control, you implicitly reference its visual hierarchy.

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

WPFWPF にはパフォーマンス プロファイリング ツールのセットがあります。アプリケーションの実行時動作を分析したり、適用できるパフォーマンス最適化の種類を決定したりできます。provides a suite of performance profiling tools that allow you to analyze the run-time behavior of your application and determine the types of performance optimizations you can apply. Visual Profiler ツールでは、パフォーマンス データをアプリケーションのビジュアル ツリーに直接マップすることにより、それらのデータを多彩なグラフィカル ビューで表示できます。The Visual Profiler tool provides a rich, graphical view of performance data by mapping directly to the application's visual tree. このスクリーンショットでは、Visual Profiler の [CPU 使用率] セクションに、オブジェクトの WPFWPF サービスの使用率が詳しく表示されています (レンダリングやレイアウトなど)。In this screenshot, the CPU Usage section of the Visual Profiler gives you a precise breakdown of an object's use of WPFWPF services, such as rendering and layout.

Visual Profiler の表示出力Visual Profiler display output
Visual Profiler 表示出力Visual Profiler display output

ビジュアル レンダリング動作Visual Rendering Behavior

WPFWPF では、ビジュアル オブジェクトのレンダリング動作に影響を及ぼす機能が導入されています。保持モード グラフィックス、ベクター グラフィックス、およびデバイス非依存グラフィックスです。introduces several features that affect the rendering behavior of visual objects: retained mode graphics, vector graphics, and device independent graphics.

保持モード グラフィックスRetained Mode Graphics

ビジュアル オブジェクトの役割を理解するためには、イミディエイト モードのグラフィックス システムと保持モードのグラフィックス システムの違いについて理解することが重要です。One of the keys to understanding the role of the Visual object is to understand the difference between immediate mode and retained mode graphics systems. GDI または GDI+ に基づく標準的な Win32 アプリケーションでは、イミディエイト モードのグラフィックス システムが使用されます。A standard Win32 application based on GDI or GDI+ uses an immediate mode graphics system. これは、ウィンドウのサイズ変更やオブジェクトの外観変更などといったアクションによって無効化されたクライアント領域の部分を、アプリケーションが再描画するということを意味します。This means that the application is responsible for repainting the portion of the client area that is invalidated, due to an action such as a window being resized, or an object changing its visual appearance.

Win32 レンダリング シーケンスのダイアグラム

これに対し、WPFWPF では、保持モード システムが使用されます。In contrast, WPFWPF uses a retained mode system. これは、外観を持つアプリケーション オブジェクト側で、シリアル化された一連の描画データが定義されるということを意味します。This means application objects that have a visual appearance define a set of serialized drawing data. 描画データが定義された後は、アプリケーション オブジェクトをレンダリングするためのすべての再描画要求に、システム側が対応します。Once the drawing data is defined, the system is responsible thereafter for responding to all repaint requests for rendering the application objects. 実行時であっても、アプリケーション オブジェクトを変更したり作成した場合の描画要求への対応は、システムに任せることができます。Even at run time, you can modify or create application objects, and still rely on the system for responding to paint requests. 保持モードのグラフィックス システムでは、描画情報が常にシリアル化された状態でアプリケーションに保持されますが、レンダリングはシステムによって実行されます。これが、保持モードのグラフィックス システムの長所です。The power in a retained mode graphics system is that drawing information is always persisted in a serialized state by the application, but rendering responsibility left to the system. 次の図は、アプリケーションでの描画要求が WPFWPF によって処理される様子を示したものです。The following diagram shows how the application relies on WPFWPF for responding to paint requests.

WPF レンダリング シーケンスのダイアグラム

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

保持モード グラフィックスを使用することの最も大きな利点の 1 つは、アプリケーション内のどの項目を再描画するのかを、WPFWPF が効率的に最適化できることです。One of the biggest benefits in using retained mode graphics is that WPFWPF can efficiently optimize what needs to be redrawn in the application. さまざまな不透明度が適用された複雑なシーンがある場合でも、通常、再描画を最適化するために特殊な目的のコードを記述する必要はありません。Even if you have a complex scene with varying levels of opacity, you generally do not need to write special-purpose code to optimize redrawing. これに対し、Win32 プログラミングでは、更新領域内の再描画量を最小化してアプリケーションを最適化するために、多大な労力が費やされることもあります。Compare this with Win32 programming in which you can spend a great deal of effort in optimizing your application by minimizing the amount of redrawing in the update region. Win32 アプリケーションで再描画を最適化するための複雑な作業の例については、「Redrawing in the Update Region」(更新領域での再描画) をご覧ください。See Redrawing in the Update Region for an example of the type of complexity involved in optimizing redrawing in Win32 applications.

ベクター グラフィックスVector Graphics

WPFWPF では、がレンダリング データ形式としてベクタ グラフィックスが使用されます。uses vector graphics as its rendering data format. スケーラブル ベクター グラフィックス (SVG)、Windows メタファイル (.wmf)、TrueType フォントなどのベクター グラフィックスは、レンダリング データを格納し、それを命令リストとして伝達します。命令リストには、グラフィックス プリミティブを使用してイメージを再作成するための方法が記述されます。Vector graphics—which include Scalable Vector Graphics (SVG), Windows metafiles (.wmf), and TrueType fonts—store rendering data and transmit it as a list of instructions that describe how to recreate an image using graphics primitives. たとえば、TrueType フォントは、ピクセル配列ではなく、直線、曲線、およびコマンドのセットで表されるアウトライン フォントです。For example, TrueType fonts are outline fonts that describe a set of lines, curves, and commands, rather than an array of pixels. ベクター グラフィックスの主な利点の 1 つは、任意のサイズや解像度に拡大縮小できることです。One of the key benefits of vector graphics is the ability to scale to any size and resolution.

ビットマップ グラフィックスは、ベクター グラフィックスとは異なり、特定の解像度で事前にレンダリングされた、ピクセル単位のイメージ表現としてレンダリング データを格納します。Unlike vector graphics, bitmap graphics store rendering data as a pixel-by-pixel representation of an image, pre-rendered for a specific resolution. ビットマップ グラフィックス形式とベクター グラフィックス形式の主な違いの 1 つは、元のソース イメージへの忠実性です。One of the key differences between bitmap and vector graphic formats is fidelity to the original source image. たとえば、ソース イメージのサイズを変更した場合、ビットマップ グラフィックス システムではイメージが伸縮されますが、ベクタ グラフィックス システムでは、イメージが拡大縮小されるため、イメージの忠実性が維持されます。For example, when the size of a source image is modified, bitmap graphics systems stretch the image, whereas vector graphics systems scale the image, preserving the image fidelity.

次の図は、ソース イメージが 300% に拡大された場合の例です。The following illustration shows a source image that has been resized by 300%. ソース イメージをビットマップ グラフィックス イメージとして拡大したイメージには、ゆがみが生じています。ベクター グラフィックス イメージとして拡大縮小した場合、こうしたゆがみは生じません。Notice the distortions that appear when the source image is stretched as a bitmap graphics image rather than scaled as a vector graphics image.

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

次のマークアップは、定義されている2つの @no__t 0 要素を示しています。The following markup shows two Path elements defined. 2番目の要素は ScaleTransform を使用して、最初の要素の描画命令のサイズを 300% で変更します。The second element uses a ScaleTransform to resize the drawing instructions of the first element by 300%. @No__t 0 の要素の描画命令は変更されていないことに注意してください。Notice that the drawing instructions in the Path elements remain unchanged.

<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>

解像度とデバイス非依存グラフィックスについてAbout Resolution and Device-Independent Graphics

画面上のテキストやグラフィックスのサイズを決定するシステム要素は、2 つあります。解像度と DPI です。There are two system factors that determine the size of text and graphics on your screen: resolution and DPI. 解像度は、画面に表示されるピクセルの数を表します。Resolution describes the number of pixels that appear on the screen. 解像度が高くなると、ピクセルが小さくなり、グラフィックスとテキストがより滑らかに表示されます。As the resolution gets higher, pixels get smaller, causing graphics and text to appear smaller. モニターの解像度が 1024 x 768 に設定されている場合、解像度を 1600 x 1200 に変更すると、表示されるグラフィックスがより小さくなります。A graphic displayed on a monitor set to 1024 x 768 will appear much smaller when the resolution is changed to 1600 x 1200.

もう 1 つのシステム設定である DPI は、画面上の 1 インチのサイズをピクセル単位で表したものです。The other system setting, DPI, describes the size of a screen inch in pixels. ほとんどの Windows システムでは DPI が96であるため、画面インチは96ピクセルです。Most Windows systems have a DPI of 96, which means a screen inch is 96 pixels. DPI の設定を上げると、画面上の 1 インチが長くなり、設定を下げると、画面上の 1 インチが短くなります。Increasing the DPI setting makes the screen inch larger; decreasing the DPI makes the screen inch smaller. そのため、ほとんどのシステムでは、画面上の 1 インチと実際の 1 インチが同じサイズにはなりません。This means that a screen inch isn't the same size as a real-world inch; on most systems, it's probably not. DPI を大きくすると、画面上の 1 インチのサイズが大きくなるため、DPI 対応のグラフィックスとテキストは大きくなります。As you increase the DPI, DPI-aware graphics and text become larger because you've increased the size of the screen inch. DPI を大きくすると、特に高解像度の場合にはテキストが読みやすくなります。Increasing the DPI can make text easier to read, especially at high resolutions.

ただし、すべてのアプリケーションが DPI に対応しているわけではありません。一部のアプリケーションでは、主要な測定単位としてハードウェア ピクセルが使用されているため、システム DPI を変更しても影響がありません。Not all applications are DPI-aware: some use hardware pixels as the primary unit of measurement; changing the system DPI has no effect on these applications. また、フォント サイズに DPI 対応の単位を使用している場合でも、それ以外の項目にはすべてピクセルを使用するアプリケーションが数多く存在します。Many other applications use DPI-aware units to describe font sizes, but use pixels to describe everything else. これらのアプリケーションで DPI を過度に小さくしたり、大きくしたりした場合、アプリケーションのテキストはシステムの DPI 設定に従って拡大縮小されますが、アプリケーションの UI は拡大縮小されないため、レイアウトの問題が発生する可能性があります。Making the DPI too small or too large can cause layout problems for these applications, because the applications' text scales with the system's DPI setting, but the applications' UI does not. この問題は、WPFWPF を使用して開発されたアプリケーションでは発生しません。This problem has been eliminated for applications developed using WPFWPF.

WPFWPF では、ハードウェア ピクセルの代わりに、デバイス非依存のピクセルを主要測定単位として用いた、自動拡大縮小機能がサポートされています。つまり、アプリケーション開発者が手を加えなくても、グラフィックスとテキストが適切に拡大縮小されます。supports automatic scaling by using the device independent pixel as its primary unit of measurement, instead of hardware pixels; graphics and text scale properly without any extra work from the application developer. 次の図は、WPFWPF のテキストとグラフィックスが、さまざまな DPI でどのように表示されるかを示したものです。The following illustration shows an example of how WPFWPF text and graphics are appear at different DPI settings.

異なる DPI 設定のグラフィックスとテキストGraphics and text at different DPI settings
異なる DPI 設定のグラフィックスとテキストGraphics and text at different DPI settings

VisualTreeHelper クラスVisualTreeHelper Class

@No__t 0 クラスは、ビジュアルオブジェクトレベルでのプログラミングのための低レベルの機能を提供する静的ヘルパークラスです。これは、高パフォーマンスのカスタムコントロールの開発など、非常に具体的なシナリオで役に立ちます。The VisualTreeHelper class is a static helper class that provides low-level functionality for programming at the visual object level, which is useful in very specific scenarios, such as developing high-performance custom controls. ほとんどの場合、CanvasTextBlock などの上位レベルの @no__t 0 framework オブジェクトでは、柔軟性と使いやすさが向上しています。In most case, the higher-level WPFWPF framework objects, such as Canvas and TextBlock, offer greater flexibility and ease of use.

ヒット テストHit Testing

@No__t-0 クラスは、既定のヒットテストのサポートがニーズを満たさない場合に、ビジュアルオブジェクトに対してヒットテストを行うためのメソッドを提供します。The VisualTreeHelper class provides methods for hit testing on visual objects when the default hit test support does not meet your needs. @No__t-1 クラスの @no__t 0 メソッドを使用して、geometry 値またはポイント座標値が、コントロールやグラフィック要素など、特定のオブジェクトの境界内にあるかどうかを判断できます。You can use the HitTest methods in the VisualTreeHelper class to determine whether a geometry or point coordinate value is within the boundary of a given object, such as a control or graphic element. たとえば、ヒット テストを使用して、オブジェクトの四角形領域内でのマウス クリックが円のジオメトリ内にあるかどうかを確認することもできます。また、ヒット テストの既定の実装をオーバーライドして、独自のカスタム ヒット テスト計算を実行することもできます。For example, you could use hit testing to determine whether a mouse click within the bounding rectangle of an object falls within the geometry of a circle You can also choose to override the default implementation of hit testing to perform your own custom hit test calculations.

ヒット テストについて詳しくは、「ビジュアル層でのヒット テスト」をご覧ください。For more information on hit testing, see Hit Testing in the Visual Layer.

ビジュアル ツリーを列挙するEnumerating the Visual Tree

@No__t-0 クラスは、ビジュアルツリーのメンバーを列挙するための機能を提供します。The VisualTreeHelper class provides functionality for enumerating the members of a visual tree. 親を取得するには、GetParent メソッドを呼び出します。To retrieve a parent, call the GetParent method. ビジュアルオブジェクトの子 (直接の子孫) を取得するには、GetChild メソッドを呼び出します。To retrieve a child, or direct descendant, of a visual object, call the GetChild method. このメソッドは、指定されたインデックス位置にある親の子 @no__t 0 を返します。This method returns a child Visual of the parent at the specified index.

次の例に示すのは、ビジュアル オブジェクトのすべての子孫を列挙する方法です。これは、ビジュアル オブジェクト階層のすべての描画情報をシリアル化する必要がある場合に使用できる手法です。The following example shows how to enumerate all the descendants of a visual object, which is a technique you might want to use if you were interested in serializing all the rendering information of a visual object hierarchy.

// 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

ほとんどの場合、WPFWPF アプリケーションの要素を表すのには、論理ツリーの方が役立ちます。In most cases, the logical tree is a more useful representation of the elements in a WPFWPF application. 論理ツリーを直接変更することはありませんが、アプリケーションのこのビューは、プロパティの継承やイベントのルーティングを理解する上で役立ちます。Although you do not modify the logical tree directly, this view of the application is useful for understanding property inheritance and event routing. ビジュアルツリーとは異なり、論理ツリーは、ListItem などの非ビジュアルデータオブジェクトを表すことができます。Unlike the visual tree, the logical tree can represent non-visual data objects, such as ListItem. 論理ツリーについて詳しくは、「WPF のツリー」をご覧ください。For more information on the logical tree, see Trees in WPF.

@No__t-0 クラスは、ビジュアルオブジェクトの外接する四角形を返すメソッドを提供します。The VisualTreeHelper class provides methods for returning the bounding rectangle of visual objects. @No__t-0 を呼び出すことによって、ビジュアルオブジェクトの外接する四角形を返すことができます。You can return the bounding rectangle of a visual object by calling GetContentBounds. @No__t-0 を呼び出すことによって、ビジュアルオブジェクト自体を含む、ビジュアルオブジェクトのすべての子孫の外接する四角形を返すことができます。You can return the bounding rectangle of all the descendants of a visual object, including the visual object itself, by calling GetDescendantBounds. 次のコードは、ビジュアル オブジェクトとそのすべての子孫の四角形領域を計算する方法を示したものです。The following code shows how you would calculate the bounding rectangle of a visual object and all its descendants.

// 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)

関連項目See also