Verwenden von DrawingVisual-Objekten
Dieses Thema bietet einen Überblick über die Verwendung von DrawingVisual-Objekten in der visuellen Ebene von WPF.
Dieses Thema enthält folgende Abschnitte.
DrawingVisual-Objekt
DrawingVisual-Hostcontainer
Erstellen von DrawingVisual-Objekten
Erstellen von Überschreibungen für FrameworkElement-Member
Bereitstellen von Unterstützung für Treffertests
Verwandte Themen
DrawingVisual-Objekt
DrawingVisual ist eine einfache Zeichnungsklasse, die verwendet wird, um Formen, Bilder oder Text zu rendern. Diese Klasse wird als einfach angesehen, weil sie weder Layout noch Ereignisbehandlung bereitstellt. Dadurch wird die Leistung gesteigert. Aus diesem Grund sind Zeichnungen ideal für Hintergründe und ClipArt.
DrawingVisual-Hostcontainer
Um DrawingVisual-Objekte verwenden zu können, müssen Sie einen Hostcontainer für die Objekte erstellen. Das Hostcontainerobjekt muss von der FrameworkElement-Klasse abgeleitet werden, die die in der DrawingVisual-Klasse nicht verfügbare Layout- und Ereignisbehandlungsunterstützung bereitstellt. Das Hostcontainerobjekt zeigt keine sichtbaren Eigenschaften, da sein Hauptzweck im Aufnehmen untergeordneter Objekte besteht. Die Visibility-Eigenschaft des Hostcontainers muss jedoch auf Visible festgelegt werden. Andernfalls würden die untergeordneten Objekte nicht angezeigt.
Wenn Sie ein Hostcontainerobjekt für visuelle Objekte erstellen, müssen Sie die Verweise für die visuellen Objekte in einer VisualCollection speichern. Verwenden Sie die Add-Methode, um dem Hostcontainer ein visuelles Objekt hinzuzufügen. In dem folgenden Beispiel wird ein Hostcontainerobjekt erstellt, und es werden drei visuelle Objekte zu dessen VisualCollection hinzugefügt.
' 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
// 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);
}
![]() |
---|
Das vollständige Codebeispiel, aus dem das vorangehende Codebeispiel extrahiert wurde, finden Sie unter Beispiel für Treffertests mit "DrawingVisuals". |
Erstellen von DrawingVisual-Objekten
Wenn Sie ein DrawingVisual-Objekt erstellen, besitzt dieses keinen Zeichnungsinhalt. Sie können Text-, Grafik- oder Bildinhalt hinzufügen, indem Sie den DrawingContext des Objekts und die Zeichnung abrufen. Ein DrawingContext wird zurückgegeben, wenn Sie die RenderOpen-Methode eines DrawingVisual-Objekts aufrufen.
Um ein Rechteck in den DrawingContext zu zeichnen, verwenden Sie die DrawRectangle-Methode des DrawingContext-Objekts. Ähnliche Methoden sind auch zum Zeichnen anderer Inhaltstypen verfügbar. Wenn Sie den Inhalt in den DrawingContext gezeichnet haben, rufen Sie die Close-Methode auf, um den DrawingContext zu schließen und den Inhalt beizubehalten.
Im folgenden Beispiel wird ein DrawingVisual-Objekt erstellt, und es wird ein Rechteck in seinen DrawingContext gezeichnet.
' 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
// 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;
}
Erstellen von Überschreibungen für FrameworkElement-Member
Das Hostcontainerobjekt verwaltet die zugehörige Auflistung visueller Objekte. Hierzu muss der Hostcontainer Memberüberschreibungen für die abgeleitete FrameworkElement-Klasse implementieren.
Die folgende Liste beschreibt die zwei Member, die Sie überschreiben müssen:
GetVisualChild: Gibt ein untergeordnetes Element am angegebenen Index aus der Auflistung der untergeordneten Elemente zurück.
VisualChildrenCount: Ruft die Anzahl visueller untergeordneter Elemente innerhalb dieses Elements ab.
Im folgenden Beispiel werden Überschreibungen für die zwei FrameworkElement-Member implementiert.
' 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
// 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];
}
Bereitstellen von Unterstützung für Treffertests
Das Hostcontainerobjekt ermöglicht eine Ereignisbehandlung, auch wenn keine sichtbaren Eigenschaften angezeigt werden. Hierzu muss jedoch die Visibility-Eigenschaft auf Visible festgelegt sein. Sie können so eine Ereignisbehandlungsroutine für den Hostcontainer erstellen, durch die Mausereignisse erfasst werden, z. B. das Loslassen der linken Maustaste. Die Ereignisbehandlungsroutine kann dann Treffertests implementieren, indem sie die HitTest-Methode aufruft. Der HitTestResultCallback-Parameter der Methode bezieht sich auf eine benutzerdefinierte Prozedur, mit der Sie die resultierende Aktion für einen Treffertest bestimmen können.
Im folgenden Beispiel wird die Unterstützung für Treffertests für das Hostcontainerobjekt und die untergeordneten Elemente implementiert.
' 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)
' Retreive 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
// 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)
{
// Retreive 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;
}