Dela via


Översikt över WPF-grafikrendering

Det här avsnittet innehåller en översikt över det visuella WPF-lagret. Den fokuserar på rollen för klassen Visual för återgivningsstöd i WPF-modellen.

Det visuella objektets roll

Klassen Visual är den grundläggande abstraktion som varje FrameworkElement objekt härleder från. Det fungerar också som startpunkt för att skriva nya kontroller i WPF, och kan på många sätt betraktas som fönsterhandtaget (HWND) i Win32-programmodellen.

Det Visual objektet är ett wpf-kärnobjekt vars primära roll är att tillhandahålla återgivningsstöd. Användargränssnittskontroller, till exempel Button och TextBox, härleds från klassen Visual och använder den för att bevara sina återgivningsdata. Objektet Visual har stöd för:

  • Utdatavisning: Återge det bevarade, serialiserade ritningsinnehållet i ett visuellt objekt.

  • Transformeringar: Utföra transformeringar på ett visuellt objekt.

  • Urklipp: Ge stöd för urklippsregion för ett visuellt objekt.

  • Träfftestning: Avgöra om en koordinat eller geometri finns inom gränserna för ett visuellt objekt.

  • Beräkningar av avgränsningsrutor: Fastställa avgränsningsrektangeln för ett visuellt objekt.

Det Visual objektet innehåller dock inte stöd för icke-återgivningsfunktioner, till exempel:

  • Händelsehantering

  • Layout

  • Stilar

  • Databindning

  • Globalisering

Visual exponeras som en offentlig abstrakt klass från vilken subklasser måste härledas. Följande bild visar hierarkin för de visuella objekt som exponeras i WPF.

diagram över klasser som härletts från visualiseringsobjektet

DrawingVisual-klass

DrawingVisual är en lätt ritningsklass som används för att återge former, bilder eller text. Den här klassen anses vara enkel eftersom den inte tillhandahåller layout eller händelsehantering, vilket förbättrar körningsprestandan. Därför är ritningar idealiska för bakgrunder och ClipArt. DrawingVisual kan användas för att skapa ett anpassat visuellt objekt. Mer information finns i Using DrawingVisual Objects.

Viewport3DVisual-klass

I Viewport3DVisual finns en brygga mellan 2D-Visual och Visual3D objekt. Klassen Visual3D är basklassen för alla visuella 3D-element. Viewport3DVisual kräver att du definierar ett Camera-värde och ett Viewport värde. Med kameran kan du se scenen. Viewporten fastställer var projektionen mappar till 2D-ytan. Mer information om 3D i WPF finns i 3D-grafiköversikt.

ContainerVisual-klass

Klassen ContainerVisual används som en container för en samling Visual objekt. Klassen DrawingVisual härleds från klassen ContainerVisual, så att den kan innehålla en samling visuella objekt.

Rita innehåll i visuella objekt

Ett Visual-objekt lagrar sina renderingsdata som en vektorgrafikinstruktionslista. Varje objekt i instruktionslistan representerar en uppsättning grafikdata på låg nivå och associerade resurser i ett serialiserat format. Det finns fyra olika typer av återgivningsdata som kan innehålla ritningsinnehåll.

Innehållstyp för ritning Beskrivning
Vektorgrafik Representerar vektorgrafikdata och eventuell associerad Brush och Pen information.
Bild Representerar en bild inom en region som definierats av en Rect.
Glyf Representerar en ritning som renderar en GlyphRun, vilket är en sekvens med tecken från en angiven teckensnittsresurs. Det är så här texten representeras.
Video Representerar en avbildning för videorendering.

Med DrawingContext kan du fylla i en Visual med visuellt innehåll. När du använder ett DrawingContext-objekts ritningskommandon lagrar du faktiskt en uppsättning återgivningsdata som senare kommer att användas av grafiksystemet; du ritar inte till skärmen i realtid.

När du skapar en WPF-kontroll, till exempel en Button, genererar kontrollen implicit återgivningsdata för själva ritningen. Om du till exempel anger egenskapen Content för Button gör att kontrollen lagrar en återgivningsrepresentation av en glyf.

En Visual beskriver innehållet som ett eller flera Drawing objekt som finns i en DrawingGroup. En DrawingGroup beskriver även ogenomskinlighetsmasker, transformeringar, bitmappseffekter och andra åtgärder som tillämpas på dess innehåll. DrawingGroup åtgärder tillämpas i följande ordning när innehåll återges: OpacityMask, Opacity, BitmapEffect, ClipGeometry, GuidelineSetoch sedan Transform.

Följande bild visar i vilken ordning DrawingGroup åtgärder tillämpas under återgivningssekvensen.

Ordningen för operationer i DrawingGroup
Ordningen på DrawingGroup-åtgärder

Mer information finns i översikten över ritobjekt .

Rita innehåll på det visuella lagret

Du instansierar aldrig direkt en DrawingContext; Du kan dock hämta en ritningskontext från vissa metoder, till exempel DrawingGroup.Open och DrawingVisual.RenderOpen. I följande exempel hämtas en DrawingContext från en DrawingVisual och använder den för att rita en rektangel.

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

Räkna upp ritningsinnehåll på det visuella lagret

Förutom andra användningsområden tillhandahåller Drawing objekt också en objektmodell för att räkna upp innehållet i en Visual.

Note

När du räknar upp innehållet i det visuella objektet hämtar du Drawing objekt och inte den underliggande representationen av återgivningsdata som en instruktionslista för vektorgrafik.

I följande exempel används metoden GetDrawing för att hämta DrawingGroup värdet för en Visual och räkna upp den.

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

Hur visuella objekt används för att skapa kontroller

Många av objekten i WPF består av andra visuella objekt, vilket innebär att de kan innehålla varierande hierarkier med underordnade objekt. Många av användargränssnittselementen i WPF, till exempel kontroller, består av flera visuella objekt som representerar olika typer av renderingselement. Kontrollen Button kan till exempel innehålla ett antal andra objekt, inklusive ClassicBorderDecorator, ContentPresenteroch TextBlock.

Följande kod visar en Button-kontroll som är definierad i markup.

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

Om du skulle räkna upp de visuella objekt som utgör standardkontrollen Button skulle du hitta hierarkin för visuella objekt som illustreras nedan:

Diagram över den visuella trädhierarkin

Kontrollen Button innehåller ett ClassicBorderDecorator element som i sin tur innehåller ett ContentPresenter element. Elementet ClassicBorderDecorator ansvarar för att rita en kantlinje och en bakgrund för Button. Elementet ContentPresenter ansvarar för att visa innehållet i Button. I det här fallet, eftersom du visar text, innehåller elementet ContentPresenter ett TextBlock element. Det faktum att Button-kontrollen använder en ContentPresenter innebär att innehållet kan representeras av andra element, till exempel en Image eller en geometri, till exempel en EllipseGeometry.

Kontrollmallar

Nyckeln till att utöka en kontroll till en hierarki med kontroller är ControlTemplate. En kontrollmall anger den visuella standardhierarkin för en kontroll. När du uttryckligen refererar till en kontroll refererar du implicit till dess visuella hierarki. Du kan åsidosätta standardvärdena för en kontrollmall för att skapa ett anpassat visuellt utseende för en kontroll. Du kan till exempel ändra bakgrundsfärgvärdet för Button-kontrollen så att den använder ett linjärt toningsfärgvärde i stället för ett fast färgvärde. Se knappformat och mallarför mer information.

Ett användargränssnittselement, till exempel en Button kontroll, innehåller flera vektorgrafikinstruktionslistor som beskriver hela renderingsdefinitionen för en kontroll. Följande kod visar en Button-kontroll som definierats i markeringsspråk.

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

Om du skulle räkna upp de visuella objekt och vektorgrafikinstruktionslistor som utgör Button kontroll, skulle du hitta hierarkin med objekt som illustreras nedan:

Diagram över visualiserat träd och dataåtergivning

Kontrollen Button innehåller ett ClassicBorderDecorator element som i sin tur innehåller ett ContentPresenter element. Elementet ClassicBorderDecorator ansvarar för att rita alla diskreta grafiska element som utgör en knapps kantlinje och bakgrund. Elementet ContentPresenter ansvarar för att visa innehållet i Button. I det här fallet, eftersom du visar en bild, innehåller elementet ContentPresenter ett Image element.

Det finns ett antal punkter att notera om hierarkin för visuella objekt och instruktionslistor för vektorgrafik:

  • Ordningen i hierarkin representerar återgivningsordningen för ritningsinformationen. Från det visuella rotelementet gås underordnade element igenom från vänster till höger och uppifrån och ned. Om ett element har visuella barnelement genomsöks de före elementets syskonelement.

  • Mellanliggande nod-element i hierarkin, till exempel ContentPresenter, används för att rymma underordnade element – de innehåller inte instruktionslistor.

  • Om ett visuellt element innehåller både en lista med vektorgrafikinstruktioner och visuella underordnade objekt återges instruktionslistan hos det överordnade visuella elementet innan ritningarna i något av de visuella underordnade objekten.

  • Objekten i instruktionslistan för vektorgrafik återges från vänster till höger.

Visuellt träd

Det visuella trädet innehåller alla visuella element som används i ett programs användargränssnitt. Eftersom ett visuellt element innehåller beständig ritningsinformation kan du se det visuella trädet som ett scendiagram som innehåller all återgivningsinformation som behövs för att skriva utdata till visningsenheten. Det här trädet är ackumuleringen av alla visuella element som skapats direkt av programmet, oavsett om de finns i kod eller i markering. Det visuella trädet innehåller också alla visuella element som skapats av mallexpansionen av element som kontroller och dataobjekt.

Följande kod visar ett StackPanel-element som definierats i markupen.

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

Om du skulle räkna upp de visuella objekt som utgör det StackPanel elementet i markeringsexemplet skulle du hitta hierarkin för visuella objekt som illustreras nedan:

Diagram över en StackPanel-kontrolls visuella trädhierarki.

Återgivningsordning

Det visuella trädet bestämmer renderingsordningen för WPF-visuella objekt och ritade objekt. Genomgångsordningen börjar med det visuella rotobjektet, som är den högsta noden i det visuella trädet. Rotvisualens barn traverseras sedan från vänster till höger. Om ett visuellt objekt har underordnade objekt traverseras dess underordnade objekt före visuella objekts syskon. Det innebär att innehållet i ett barnvisuellt objekt visas framför det visuella objektets eget innehåll.

diagram över den visuella trädrenderingsordningen

Rotvisualisering

Det visuella rotobjektet är det översta elementet i en visuell trädhierarki. I de flesta program är basklassen för det visuella rotobjektet antingen Window eller NavigationWindow. Men om du värdar visuella objekt i en Win32-applikation skulle det visuella rotobjektet vara det översta visuella objektet som du värdar i Win32-fönstret. För mer information, se Handledning: Hosting av visuella objekt i ett Win32-program.

Relation till det logiska trädet

Det logiska trädet i WPF representerar elementen i ett program vid körning. Även om du inte ändrar det här trädet direkt är den här vyn av programmet användbar för att förstå egenskapsarv och händelseroutning. Till skillnad från det visuella trädet kan det logiska trädet representera icke-visuella dataobjekt, till exempel ListItem. I många fall mappar det logiska trädet mycket nära en applikations markupdefinitioner. Följande kod visar ett DockPanel-element, som definierats i markup.

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

Om du skulle räkna upp de logiska objekt som utgör det DockPanel elementet i markeringsexemplet skulle du hitta hierarkin för logiska objekt som illustreras nedan:

träddiagram
Diagram över logiskt träd

Både det visuella trädet och det logiska trädet synkroniseras med den aktuella uppsättningen programelement, vilket återspeglar eventuella tillägg, borttagning eller ändringar av element. Träden erbjuder dock olika vyer av programmet. Till skillnad från det visuella trädet expanderar inte det logiska trädet en kontrolls ContentPresenter element. Det innebär att det inte finns någon direkt en-till-en-korrespondens mellan ett logiskt träd och ett visuellt träd för samma uppsättning objekt. Att anropa LogicalTreeHelper-objektets GetChildren-metod och VisualTreeHelper objektets GetChild-metod med samma element som en parameter ger faktiskt olika resultat.

Mer information om det logiska trädet finns i Träd i WPF.

Visa det visuella trädet med XamlPad

WPF-verktyget XamlPad ger ett alternativ för att visa och utforska det visuella trädet som motsvarar det för närvarande definierade XAML-innehållet. Klicka på knappen Visa visuellt träd på menyraden för att visa det visuella trädet. Följande illustrerar expansionen av XAML-innehåll till visuella trädnoder i Visual Tree Explorer panelen i XamlPad:

fönstret Visual Tree Explorer i XamlPad

Observera hur kontrollerna Label, TextBoxoch Button visar en separat objekthierarki i Visual Tree Explorer panelen i XamlPad. Det beror på att WPF-kontroller har en ControlTemplate som innehåller kontrollens visuella träd. När du uttryckligen refererar till en kontroll refererar du implicit till dess visuella hierarki.

Profilering av visuella prestanda

WPF tillhandahåller en uppsättning verktyg för prestandaprofilering som gör att du kan analysera körningsbeteendet för ditt program och fastställa vilka typer av prestandaoptimeringar du kan använda. Verktyget Visual Profiler ger en omfattande, grafisk vy över prestandadata genom att mappa direkt till programmets visuella träd. I den här skärmbilden ger avsnittet CPU-användning i Visual Profiler en exakt uppdelning av ett objekts användning av WPF-tjänster, till exempel rendering och layout.

Visual Profiler visar utdata
Visningsutdata för Visual Profiler

Visuellt återgivningsbeteende

WPF introducerar flera funktioner som påverkar återgivningsbeteendet för visuella objekt: grafik i behållet läge, vektorgrafik och enhetsoberoende grafik.

Grafik för behållet läge

En av nycklarna till att förstå det visuella objektets roll är att förstå skillnaden mellan omedelbart läge och behållet läge grafiksystem. Ett Win32-standardprogram baserat på GDI eller GDI+ använder ett grafiksystem i omedelbart läge. Det innebär att programmet ansvarar för att måla om den del av klientområdet som har ogiltigförklarats, på grund av en åtgärd som att ett fönster ändras eller att ett objekt ändrar dess visuella utseende.

diagram över Win32-renderingssekvens

WPF använder däremot ett system för behållet läge. Det innebär att programobjekt som har ett visuellt utseende definierar en uppsättning serialiserade ritningsdata. När ritningsdata har definierats ansvarar systemet därefter för att svara på alla omformningsbegäranden för att återge programobjekten. Även vid körning kan du ändra eller skapa programobjekt och fortfarande förlita dig på systemet för att svara på färgbegäranden. Styrkan med ett grafiksystem i bevarat läge är att ritningsinformation alltid bevaras i ett serialiserat tillstånd av programmet, men att rendreringsansvaret lämnas till systemet. Följande diagram visar hur programmet förlitar sig på WPF för att svara på färgbegäranden.

diagram över WPF-renderingssekvens

Intelligent omritning

En av de största fördelarna med att använda grafik i behållet läge är att WPF effektivt kan optimera det som behöver ritas om i programmet. Även om du har en komplex scen med varierande opacitetsnivåer behöver du vanligtvis inte skriva kod för att optimera omritning. Jämför detta med Win32-programmering där du kan ägna mycket arbete åt att optimera programmet genom att minimera mängden omritning i uppdateringsområdet. Se Redrawing inom uppdateringsområdet för ett exempel på vilken komplexitet som ingår i optimeringen av omritning i Win32-applikationer.

Vektorgrafik

WPF använder vektorgrafik som återgivningsdataformat. Vektorgrafik – som omfattar skalbar vektorgrafik (SVG), Windows-metafiler (.wmf) och TrueType-teckensnitt – lagrar återgivningsdata och överför dem som en lista med instruktioner som beskriver hur du återskapar en bild med hjälp av grafikprimitiver. TrueType-teckensnitt är till exempel dispositionsteckensnitt som beskriver en uppsättning rader, kurvor och kommandon i stället för en matris med bildpunkter. En av de viktigaste fördelarna med vektorgrafik är möjligheten att skala till valfri storlek och upplösning.

Till skillnad från vektorgrafik, lagrar bitmappsgrafik återgivningsdata som en pixel-för-pixel representation av en bild, för-renderad för en specifik upplösning. En av de viktigaste skillnaderna mellan bitmapps- och vektorgrafikformat är återgivning till den ursprungliga källbilden. När till exempel storleken på en källbild ändras sträcker bitmappsgrafiksystem ut bilden, medan vektorgrafiksystem skalar bilden och bevarar bildåtergivningen.

Följande illustration visar en källbild som har storlekändrats till 300%. Observera de snedvridningar som visas när källbilden sträcks ut som en bitmappsgrafikbild i stället för att skalas som en vektorgrafikbild.

Skillnader mellan raster- och vektorgrafik

Följande markering visar två Path definierade element. Det andra elementet använder en ScaleTransform för att ändra storlek på ritningsinstruktionerna för det första elementet med 300%. Observera att ritningsinstruktionerna i de Path elementen förblir oförändrade.

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

Om upplösning och Device-Independent grafik

Det finns två systemfaktorer som avgör storleken på text och grafik på skärmen: upplösning och DPI. Upplösningen beskriver antalet bildpunkter som visas på skärmen. När upplösningen blir högre blir bildpunkterna mindre, vilket gör att grafik och text blir mindre. En bild som visas på en bildskärm som är inställd på 1 024 x 768 visas mycket mindre när upplösningen ändras till 1600 x 1 200.

Den andra systeminställningen, DPI, beskriver storleken på en skärmtum i bildpunkter. De flesta Windows-system har en DPI på 96, vilket innebär att en skärmtum är 96 bildpunkter. Om du ökar DPI-inställningen blir skärmens tum större. minskar DPI:et gör skärmens tum mindre. Det innebär att en skärmtum inte har samma storlek som en verklig tum. på de flesta system är det förmodligen inte. När du ökar DPI:et blir DPI-medveten grafik och text större eftersom du har ökat storleken på skärmtum. Om du ökar DPI:et blir det lättare att läsa texten, särskilt vid höga upplösningar.

Alla program är inte DPI-medvetna: vissa använder maskinvarupixlar som den primära måttenheten. att ändra system-DPI:n har ingen effekt på dessa program. Många andra program använder DPI-medvetna enheter för att beskriva teckenstorlekar, men använder pixlar för att beskriva allt annat. Att göra DPI:et för litet eller för stort kan orsaka layoutproblem för dessa program, eftersom programmens text skalas med systemets DPI-inställning, men inte programmets användargränssnitt. Det här problemet har eliminerats för program som utvecklats med WPF.

WPF stöder automatisk skalning med hjälp av enhetens oberoende pixel som primär måttenhet, i stället för maskinvarupixlar. grafik och text skalas korrekt utan extra arbete från programutvecklaren. Följande bild visar ett exempel på hur WPF-text och grafik visas med olika DPI-inställningar.

grafik och text med olika DPI-inställningar
Grafik och text med olika DPI-inställningar

VisualTreeHelper-klass

Klassen VisualTreeHelper är en statisk hjälpklass som tillhandahåller funktioner på låg nivå för programmering på objektnivå, vilket är användbart i mycket specifika scenarier, till exempel utveckling av anpassade kontroller med höga prestanda. I de flesta fall ger WPF-ramverksobjekt på högre nivå, till exempel Canvas och TextBlock, större flexibilitet och användarvänlighet.

Träfftestning

Klassen VisualTreeHelper innehåller metoder för träfftestning på visuella objekt när standardsupporten för träfftest inte uppfyller dina behov. Du kan använda HitTest metoder i klassen VisualTreeHelper för att avgöra om ett geometri- eller punktkoordinatvärde ligger inom gränsen för ett visst objekt, till exempel ett kontroll- eller grafiskt element. Du kan till exempel använda träfftestning för att avgöra om ett musklick inom avgränsningsrektangeln för ett objekt faller inom geometrin i en cirkel Du kan också välja att åsidosätta standardimplementeringen av träfftestning för att utföra dina egna anpassade beräkningar för träfftest.

Mer information om träfftestning finns i Träfftestning i Visual Layer.

Räkna upp det visuella trädet

Klassen VisualTreeHelper innehåller funktioner för att räkna upp medlemmar i ett visuellt träd. Om du vill hämta en överordnad anropar du metoden GetParent. Anropa metoden GetChild för att hämta ett underordnat objekt eller en direkt avkomma till en visuell komponent. Den här metoden returnerar ett barnobjekt Visual av den överordnade vid det angivna indexet.

I följande exempel visas hur du räknar upp alla underordnade objekt i ett visuellt objekt, vilket är en teknik som du kanske vill använda om du är intresserad av att serialisera all återgivningsinformation för en objekthierarki för visuella objekt.

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

I de flesta fall är det logiska trädet en mer användbar representation av elementen i ett WPF-program. Även om du inte ändrar det logiska trädet direkt är den här vyn av programmet användbar för att förstå arv av egenskaper och händelseroutning. Till skillnad från det visuella trädet kan det logiska trädet representera icke-visuella dataobjekt, till exempel ListItem. Mer information om det logiska trädet finns i Träd i WPF.

Klassen VisualTreeHelper tillhandahåller metoder för att returnera den omslutande rektangeln för visuella objekt. Du kan returnera avgränsningsrektangeln för ett visuellt objekt genom att anropa GetContentBounds. Du kan returnera avgränsningsrektangeln för alla underordnade objekt, inklusive själva det visuella objektet, genom att anropa GetDescendantBounds. Följande kod visar hur du beräknar avgränsningsrektangeln för ett visuellt objekt och alla dess underordnade objekt.

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

Se även