Bagikan melalui


Menggunakan Objek DrawingVisual

Topik ini memberikan gambaran umum tentang cara menggunakan objek DrawingVisual di lapisan visual WPF.

Objek DrawingVisual

DrawingVisual adalah kelas gambar ringan yang digunakan untuk merender bentuk, gambar, atau teks. Kelas ini dianggap ringan karena tidak menyediakan pengaturan tata letak atau penanganan acara, sehingga meningkatkan performanya. Untuk alasan ini, gambar sangat ideal untuk latar belakang dan clip art.

DrawingVisual Host Container

Untuk menggunakan objek DrawingVisual, Anda perlu membuat kontainer host untuk objek. Objek kontainer host harus berasal dari kelas FrameworkElement, yang menyediakan dukungan tata letak dan penanganan peristiwa yang tidak memiliki kelas DrawingVisual. Objek kontainer host tidak menampilkan properti yang terlihat, karena tujuan utamanya adalah untuk berisi objek anak. Namun, properti Visibility kontainer host harus diatur ke Visible; jika tidak, elemen turunannya tidak akan terlihat.

Saat Anda membuat objek kontainer host untuk objek visual, Anda perlu menyimpan referensi objek visual dalam VisualCollection. Gunakan metode Add untuk menambahkan objek visual ke kontainer host. Dalam contoh berikut, objek kontainer host dibuat, dan tiga objek visual ditambahkan ke 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

Nota

Untuk melihat sampel kode lengkap dari mana contoh kode sebelumnya diambil, lihat Sampel Pengujian Tabrakan Menggunakan DrawingVisuals.

Membuat Objek DrawingVisual

Saat Anda membuat objek DrawingVisual, objek tersebut tidak memiliki konten gambar. Anda dapat menambahkan konten teks, grafik, atau gambar dengan mengambil DrawingContext objek dan menggambar ke dalamnya. DrawingContext dikembalikan dengan memanggil metode RenderOpen objek DrawingVisual.

Untuk menggambar persegi panjang pada DrawingContext, gunakan metode DrawRectangle dari objek DrawingContext. Metode serupa ada untuk menggambar jenis konten lainnya. Ketika Anda selesai menggambar konten ke dalam DrawingContext, panggil metode Close untuk menutup DrawingContext dan mempertahankan konten.

Dalam contoh berikut, objek DrawingVisual dibuat, dan sebuah persegi digambar ke dalam bagian DrawingContext-nya.

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

Membuat Penimpaan untuk Elemen FrameworkElement

Objek kontainer host bertanggung jawab untuk mengelola kumpulan objek visualnya. Ini mengharuskan kontainer host untuk mengimplementasikan penimpaan anggota pada kelas turunan FrameworkElement.

Daftar berikut ini menjelaskan dua anggota yang harus Anda ambil alih:

  • GetVisualChild: Mengembalikan anak pada indeks yang ditentukan dari kumpulan elemen anak.

  • VisualChildrenCount: Mendapatkan jumlah elemen anak visual dalam elemen ini.

Dalam contoh berikut, penggantian untuk dua anggota FrameworkElement diimplementasikan.


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

Memberikan Dukungan Pengujian Hit

Objek kontainer host dapat menyediakan penanganan peristiwa meskipun tidak menampilkan properti yang terlihat—namun, properti Visibility harus diatur ke Visible. Ini memungkinkan Anda membuat rutinitas penanganan peristiwa untuk kontainer host yang dapat mendeteksi peristiwa mouse, seperti pelepasan tombol mouse kiri. Rutinitas penanganan peristiwa kemudian dapat menerapkan pengujian hit dengan memanggil metode HitTest. Parameter HitTestResultCallback dari metode mengacu pada prosedur yang ditentukan oleh pengguna, yang dapat Anda gunakan untuk menentukan tindakan yang dihasilkan dari tes keberhasilan.

Dalam contoh berikut, dukungan pengujian hit diimplementasikan untuk objek kontainer host dan anak-anaknya.

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

Lihat juga