DrawingVisual オブジェクトの使用Using DrawingVisual Objects

このトピックでは、WPFWPF のビジュアル層で DrawingVisual オブジェクトを使用する方法の概要を示します。This topic provides an overview of how to use DrawingVisual objects in the WPFWPF visual layer.

DrawingVisual オブジェクトDrawingVisual Object

DrawingVisual は、図形、イメージ、またはテキストのレンダリングに使用する軽量の描画クラスです。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 performance. そのため、背景やクリップ アートの描画に適しています。For this reason, drawings are ideal for backgrounds and clip art.

DrawingVisual ホスト コンテナーDrawingVisual Host Container

DrawingVisual オブジェクトを使用するには、このオブジェクトのホスト コンテナーを作成する必要があります。In order to use DrawingVisual objects, you need to create a host container for the objects. ホスト コンテナー オブジェクトは、FrameworkElement クラスから派生させる必要があります。これにより、レイアウトやイベントの処理がサポートされます。これは、DrawingVisual クラスには欠落しているものです。The host container object must derive from the FrameworkElement class, which provides the layout and event handling support that the DrawingVisual class lacks. ホスト コンテナー オブジェクトの主な目的は子オブジェクトを格納することなので、ホスト コンテナー オブジェクトでは可視プロパティは表示されません。The host container object does not display any visible properties, since its main purpose is to contain child objects. ただし、ホスト コンテナーの Visibility プロパティは、Visible に設定する必要があります。このようにしないと、その子要素は一切表示されません。However, the Visibility property of the host container must be set to Visible; otherwise, none of its child elements will be visible.

ビジュアル オブジェクトのホスト コンテナー オブジェクトを作成する際には、VisualCollection にビジュアル オブジェクト参照を格納する必要があります。When you create a host container object for visual objects, you need to store the visual object references in a VisualCollection. ホスト コンテナーにビジュアル オブジェクトを追加するには、Add メソッドを使用します。Use the Add method to add a visual object to the host container. 次の例では、ホスト コンテナー オブジェクトを作成し、その VisualCollection に 3 つのビジュアル オブジェクトを追加しています。In the following example, a host container object is created, and three visual objects are added to its VisualCollection.

// Create a host visual derived from the FrameworkElement class.
// This class provides layout, event handling, and container support for
// the child visual objects.
public class MyVisualHost : FrameworkElement
{
    // Create a collection of child visual objects.
    private VisualCollection _children;

    public MyVisualHost()
    {
        _children = new VisualCollection(this);
        _children.Add(CreateDrawingVisualRectangle());
        _children.Add(CreateDrawingVisualText());
        _children.Add(CreateDrawingVisualEllipses());

        // Add the event handler for MouseLeftButtonUp.
        this.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(MyVisualHost_MouseLeftButtonUp);
    }
' Create a host visual derived from the FrameworkElement class.
' This class provides layout, event handling, and container support for
' the child visual objects.
Public Class MyVisualHost
    Inherits FrameworkElement
    ' Create a collection of child visual objects.
    Private _children As VisualCollection

    Public Sub New()
        _children = New VisualCollection(Me)
        _children.Add(CreateDrawingVisualRectangle())
        _children.Add(CreateDrawingVisualText())
        _children.Add(CreateDrawingVisualEllipses())

        ' Add the event handler for MouseLeftButtonUp.
        AddHandler MouseLeftButtonUp, AddressOf MyVisualHost_MouseLeftButtonUp
    End Sub

注意

上記のコードの抽出元となった完全なコード サンプルについては、「DrawingVisual を使用したヒット テストのサンプル」を参照してください。For the complete code sample from which the preceding code example was extracted, see Hit Test Using DrawingVisuals Sample.

Creating DrawingVisual オブジェクトの作成Creating DrawingVisual Objects

DrawingVisual オブジェクトを作成した時点では、その中に描画コンテンツは含まれていません。When you create a DrawingVisual object, it has no drawing content. テキスト、グラフィックス、またはイメージ コンテンツを追加するには、オブジェクトの DrawingContext を取得し、その中に描画します。You can add text, graphics, or image content by retrieving the object's DrawingContext and drawing into it. DrawingContext を取得するには、DrawingVisual オブジェクトの RenderOpen メソッドを呼び出します。A DrawingContext is returned by calling the RenderOpen method of a DrawingVisual object.

DrawingContext に四角形を描画するには、DrawingContext オブジェクトの DrawRectangle メソッドを使用します。To draw a rectangle into the DrawingContext, use the DrawRectangle method of the DrawingContext object. 他の種類のコンテンツを描画するための同様のメソッドもあります。Similar methods exist for drawing other types of content. DrawingContext へのコンテンツの描画が完了したら、Close メソッドを呼び出して DrawingContext を閉じ、コンテンツを永続化します。When you are finished drawing content into the DrawingContext, call the Close method to close the DrawingContext and persist the content.

次の例では、DrawingVisual オブジェクトを作成し、その DrawingContext に四角形を描画しています。In the following example, a DrawingVisual object is created, and a rectangle is drawn into its 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

FrameworkElement メンバーのオーバーライドの作成Creating Overrides for FrameworkElement Members

ホスト コンテナー オブジェクトは、ビジュアル オブジェクトのコレクションを管理します。The host container object is responsible for managing its collection of visual objects. このため、ホスト コンテナーは派生 FrameworkElement クラスのメンバーのオーバーライドを実装する必要があります。This requires that the host container implement member overrides for the derived FrameworkElement class.

オーバーライドする必要がある 2 つのメンバーを次に示します。The following list describes the two members you must override:

  • GetVisualChild:子要素のコレクションから、指定したインデックス位置の子を返します。GetVisualChild: Returns a child at the specified index from the collection of child elements.

  • VisualChildrenCount:この要素内でビジュアル子要素の数を取得します。VisualChildrenCount: Gets the number of visual child elements within this element.

次の例では、2 つの FrameworkElement メンバーのオーバーライドを実装しています。In the following example, overrides for the two FrameworkElement members are implemented.


// Provide a required override for the VisualChildrenCount property.
protected override int VisualChildrenCount
{
    get { return _children.Count; }
}

// Provide a required override for the GetVisualChild method.
protected override Visual GetVisualChild(int index)
{
    if (index < 0 || index >= _children.Count)
    {
        throw new ArgumentOutOfRangeException();
    }

    return _children[index];
}


' Provide a required override for the VisualChildrenCount property.
Protected Overrides ReadOnly Property VisualChildrenCount() As Integer
    Get
        Return _children.Count
    End Get
End Property

' Provide a required override for the GetVisualChild method.
Protected Overrides Function GetVisualChild(ByVal index As Integer) As Visual
    If index < 0 OrElse index >= _children.Count Then
        Throw New ArgumentOutOfRangeException()
    End If

    Return _children(index)
End Function

ヒット テストのサポートProviding Hit Testing Support

ホスト コンテナー オブジェクトでは、可視プロパティが表示されない場合でもイベント処理を提供できます。ただし、その Visibility プロパティを Visible に設定する必要があります。The host container object can provide event handling even if it does not display any visible properties—however, its Visibility property must be set to Visible. これにより、マウス イベント (マウスの左ボタンのリリースなど) をトラップできる、ホスト コンテナーのイベント処理ルーチンを作成できます。This allows you to create an event handling routine for the host container that can trap mouse events, such as the release of the left mouse button. イベント処理ルーチンでは、HitTest メソッドを呼び出すことでヒット テストを実施できます。The event handling routine can then implement hit testing by invoking the HitTest method. このメソッドの HitTestResultCallback パラメーターは、ヒット テストの結果アクションを決定するために使用できる、ユーザー定義のプロシージャを参照します。The method's HitTestResultCallback parameter refers to a user-defined procedure that you can use to determine the resulting action of a hit test.

次の例では、ホスト コンテナー オブジェクトとその子に対してヒット テストのサポートを実装しています。In the following example, hit testing support is implemented for the host container object and its children.

// Capture the mouse event and hit test the coordinate point value against
// the child visual objects.
void MyVisualHost_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    // Retrieve the coordinates of the mouse button event.
    System.Windows.Point pt = e.GetPosition((UIElement)sender);

    // Initiate the hit test by setting up a hit test result callback method.
    VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(myCallback), new PointHitTestParameters(pt));
}

// If a child visual object is hit, toggle its opacity to visually indicate a hit.
public HitTestResultBehavior myCallback(HitTestResult result)
{
    if (result.VisualHit.GetType() == typeof(DrawingVisual))
    {
        if (((DrawingVisual)result.VisualHit).Opacity == 1.0)
        {
            ((DrawingVisual)result.VisualHit).Opacity = 0.4;
        }
        else
        {
            ((DrawingVisual)result.VisualHit).Opacity = 1.0;
        }
    }

    // Stop the hit test enumeration of objects in the visual tree.
    return HitTestResultBehavior.Stop;
}
' Capture the mouse event and hit test the coordinate point value against
' the child visual objects.
Private Sub MyVisualHost_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    ' Retrieve the coordinates of the mouse button event.
    Dim pt As Point = e.GetPosition(CType(sender, UIElement))

    ' Initiate the hit test by setting up a hit test result callback method.
    VisualTreeHelper.HitTest(Me, Nothing, New HitTestResultCallback(AddressOf myCallback), New PointHitTestParameters(pt))
End Sub

' If a child visual object is hit, toggle its opacity to visually indicate a hit.
Public Function myCallback(ByVal result As HitTestResult) As HitTestResultBehavior
    If result.VisualHit.GetType() Is GetType(DrawingVisual) Then
        If (CType(result.VisualHit, DrawingVisual)).Opacity = 1.0 Then
            CType(result.VisualHit, DrawingVisual).Opacity = 0.4
        Else
            CType(result.VisualHit, DrawingVisual).Opacity = 1.0
        End If
    End If

    ' Stop the hit test enumeration of objects in the visual tree.
    Return HitTestResultBehavior.Stop
End Function

関連項目See also