使用 DrawingVisual 物件
本主題提供如何在 WPF 視覺化層中使用 DrawingVisual 物件的概觀。
DrawingVisual 物件
DrawingVisual是輕量型繪圖類別,用來轉譯圖形、影像或文字。 此類別之所以被視為輕量型,是因為它不提供版面配置或事件處理,這使它有更好的效能。 基於此原因,繪圖適合背景或美工圖案。
DrawingVisual 主機容器
若要使用 DrawingVisual 物件,您必須建立物件的主機容器。 主機容器物件必須衍生自 FrameworkElement 類別,其提供類別所缺少的配置和事件處理支援 DrawingVisual 。 主機容器物件不會顯示任何可見的屬性,因為其主要目的是要包含子物件。 不過, Visibility 主機容器的 屬性必須設定為 Visible ,否則不會顯示其子項目。
當您建立視覺物件的主機容器物件時,您必須將視覺物件參考儲存在 中 VisualCollection 。 Add使用 方法,將視覺物件新增至主機容器。 在下列範例中,會建立主機容器物件,並將三個視覺物件新增至其 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
注意
如需先前程式碼範例出處的完整程式碼範例,請參閱使用 DrawingVisuals 進行點擊測試範例 (英文)。
建立 DrawingVisual 物件
當您建立 DrawingVisual 物件時,它沒有繪圖內容。 您可以藉由擷取物件的 並繪製到其中 DrawingContext ,來新增文字、圖形或影像內容。 DrawingContext呼叫 物件的 方法 DrawingVisual 會傳 RenderOpen 回 。
若要將矩形繪製到 , DrawingContext 請使用 DrawRectangle 物件的 方法 DrawingContext 。 繪製其他類型的內容有類似的方法。 當您完成將內容繪製到 DrawingContext 時,請呼叫 Close 方法來關閉 DrawingContext 並保存內容。
在下列範例中, 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
針對 FrameworkElement 成員建立覆寫
主機容器物件負責管理其視覺物件的集合。 這需要主機容器實作衍生 FrameworkElement 類別的成員覆寫。
下列清單說明您必須覆寫的兩個成員︰
GetVisualChild:從子專案集合傳回位於指定索引處的子系。
VisualChildrenCount:取得這個專案內的視覺子專案數目。
在下列範例中,會實作兩 FrameworkElement 個成員的覆寫。
// 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
提供點擊測試支援
即使主機容器物件未顯示任何可見屬性,也可以提供事件處理,不過,其 Visibility 屬性必須設定為 Visible 。 這可讓您針對可捕捉滑鼠事件 (例如放開滑鼠左鍵) 的主機容器建立事件處理常式。 然後,事件處理常式可以叫 HitTest 用 方法來實作點擊測試。 方法的參數 HitTestResultCallback 是指使用者定義的程式,您可以用來判中斷點擊測試的結果動作。
在下列範例中,會針對主機容器物件和其子系實作點擊測試支援。
// 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
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應