Gör så här: Rendera för varje bildruta med CompositionTarget

WPF-animeringsmotorn innehåller många funktioner för att skapa rambaserad animering. Det finns dock programscenarier där du behöver finare kontroll över renderingen per bildruta. CompositionTarget-objektet ger möjlighet att skapa anpassade animeringar via ett återanrop per bildram.

CompositionTarget är en statisk klass som representerar visningsytan som programmet ritas på. Händelsen Rendering utlöses varje gång programmets scen ritas. Återgivningens bildhastighet är antalet gånger scenen ritas per sekund.

Anmärkning

Ett fullständigt kodexempel med CompositionTargetfinns i Using the CompositionTarget Sample.

Exempel

Händelsen Rendering utlöses under WPF-renderingsprocessen. I följande exempel visas hur du registrerar en EventHandler-delegerare för den statiska Rendering-metoden på CompositionTarget.

// Add an event handler to update canvas background color just before it is rendered.
CompositionTarget.Rendering += UpdateColor;
' Add an event handler to update canvas background color just before it is rendered.
AddHandler CompositionTarget.Rendering, AddressOf UpdateColor

Du kan använda händelsehanterarmetoden för rendering för att skapa anpassat ritningsinnehåll. Den här händelsehanterarmetoden anropas en gång per bildruta. Varje gång WPF överför de persisterade återgivningsdata i det visuella trädet till kompositionsscengrafen, anropas din händelsehanterarmetod. Dessutom, om ändringar i det visuella trädet tvingar uppdateringar av kompositionsscenens graf, anropas även din händelsehanteringsmetod. Observera att händelsehanterarmetoden anropas när layouten har beräknats. Du kan dock ändra layouten i händelsehanterarmetoden, vilket innebär att layouten beräknas en gång till innan återgivningen.

I följande exempel visas hur du kan ange anpassad ritning i en CompositionTarget händelsehanterarmetod. I det här fallet ritas bakgrundsfärgen för Canvas med ett färgvärde baserat på musens koordinatposition. Om du flyttar musen inuti Canvasändras bakgrundsfärgen. Dessutom beräknas den genomsnittliga bildfrekvensen baserat på den aktuella förflutna tiden och det totala antalet återgivna bildrutor.

// Called just before frame is rendered to allow custom drawing.
protected void UpdateColor(object sender, EventArgs e)
{
    if (_frameCounter++ == 0)
    {
        // Starting timing.
        _stopwatch.Start();
    }

    // Determine frame rate in fps (frames per second).
    long frameRate = (long)(_frameCounter / this._stopwatch.Elapsed.TotalSeconds);
    if (frameRate > 0)
    {
        // Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString();
        myFrameCounterLabel.Content = _frameCounter.ToString();
        myFrameRateLabel.Content = frameRate.ToString();
    }

    // Update the background of the canvas by converting MouseMove info to RGB info.
    byte redColor = (byte)(_pt.X / 3.0);
    byte blueColor = (byte)(_pt.Y / 2.0);
    myCanvas.Background = new SolidColorBrush(Color.FromRgb(redColor, 0x0, blueColor));
}
' Called just before frame is rendered to allow custom drawing.
Protected Sub UpdateColor(ByVal sender As Object, ByVal e As EventArgs)

    If _frameCounter = 0 Then
        ' Starting timing.
        _stopwatch.Start()
    End If
    _frameCounter = _frameCounter + 1

    ' Determine frame rate in fps (frames per second).
    Dim frameRate As Long = CLng(Fix(_frameCounter / Me._stopwatch.Elapsed.TotalSeconds))
    If frameRate > 0 Then
        ' Update elapsed time, number of frames, and frame rate.
        myStopwatchLabel.Content = _stopwatch.Elapsed.ToString()
        myFrameCounterLabel.Content = _frameCounter.ToString()
        myFrameRateLabel.Content = frameRate.ToString()
    End If

    ' Update the background of the canvas by converting MouseMove info to RGB info.
    Dim redColor As Byte = CByte(_pt.X / 3.0)
    Dim blueColor As Byte = CByte(_pt.Y / 2.0)
    myCanvas.Background = New SolidColorBrush(Color.FromRgb(redColor, &H0, blueColor))
End Sub

Du kanske upptäcker att din anpassade ritning körs i olika hastigheter på olika datorer. Det beror på att din anpassade ritning inte är oberoende av bildfrekvens. Beroende på vilket system du kör och systemets arbetsbelastning kan den Rendering händelsen kallas ett annat antal gånger per sekund. Information om hur du fastställer grafikmaskinvarans kapacitet och prestanda för en enhet som kör ett WPF-program finns i Grafikrenderingsnivåer.

Om du lägger till eller tar bort en rendering EventHandler delegering medan händelsen pågår, kommer det att fördröjas tills händelsen har avslutats. Detta överensstämmer med hur MulticastDelegate-baserade händelser hanteras i CLR (Common Language Runtime). Observera också att återgivningshändelser inte garanteras anropas i någon viss ordning. Om du har flera EventHandler ombud som förlitar sig på en viss ordning bör du registrera en enda Rendering händelse och multiplexa ombuden i rätt ordning själv.

Se även