Udostępnij przez


Instrukcje: renderowanie w interwale klatek przy użyciu elementu CompositionTarget

Aparat animacji WPF oferuje wiele funkcji do tworzenia animacji opartej na ramce. Istnieją jednak scenariusze aplikacji, w których potrzebujesz bardziej szczegółowej kontroli nad renderowaniem na podstawie każdego pojedynczego kadru. Obiekt CompositionTarget zapewnia możliwość tworzenia niestandardowych animacji na podstawie wywołania zwrotnego dla każdej klatki.

CompositionTarget jest klasą statyczną reprezentującą powierzchnię wyświetlania, na której jest rysowana aplikacja. Zdarzenie Rendering jest wywoływane za każdym razem, gdy scena aplikacji zostanie narysowana. Szybkość renderowania klatek to liczba razy, kiedy scena jest renderowana na sekundę.

Uwaga / Notatka

Aby zapoznać się z kompletnym przykładem kodu używając CompositionTarget, zobacz Korzystanie z przykładu CompositionTarget.

Przykład

Zdarzenie Rendering jest uruchamiane podczas procesu renderowania WPF. W poniższym przykładzie pokazano, jak zarejestrować delegata EventHandler przy wykorzystaniu metody statycznej Rendering na 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

Możesz użyć metody obsługi zdarzeń renderowania, aby utworzyć niestandardową treść rysunku. Ta metoda obsługi zdarzeń jest wywoływana raz na ramkę. Za każdym razem, gdy platforma WPF przekazuje utrwalone dane renderowania w drzewie wizualnym do grafu sceny kompozycji, wywoływana jest Twoja metoda obsługi zdarzeń. Ponadto jeśli zmiany w drzewie wizualnym wymuszają aktualizacje grafu sceny kompozycji, wywoływana jest również metoda obsługi zdarzeń. Pamiętaj, że metoda obsługi zdarzeń jest wywoływana po obliczeniu układu. Można jednak zmodyfikować układ w metodzie obsługi zdarzeń, co oznacza, że układ zostanie obliczony jeszcze raz przed renderowaniem.

W poniższym przykładzie pokazano, jak udostępnić niestandardowy rysunek w metodzie obsługi zdarzeń CompositionTarget . W tym przypadku kolor Canvas tła obiektu jest rysowany z wartością koloru na podstawie położenia współrzędnych myszy. Jeśli przeniesiesz mysz wewnątrz Canvaselementu , jego kolor tła zmieni się. Ponadto średnia liczba klatek na sekundę jest obliczana na podstawie obecnego upływu czasu i całkowitej liczby renderowanych klatek.

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

Możesz zauważyć, że proces niestandardowego rysowania działa z różną szybkością na różnych komputerach. Dzieje się tak, ponieważ niestandardowy rysunek nie jest niezależny od szybkości klatek. W zależności od uruchomionego systemu i obciążenia tego systemu Rendering zdarzenie może być wywoływane inną liczbę razy na sekundę. Aby uzyskać informacje na temat określania możliwości i wydajności sprzętu grafiki dla urządzenia z uruchomioną aplikacją WPF, zobacz Graphics Rendering Tiers (Warstwy renderowania grafiki).

Dodawanie lub usuwanie delegata renderowania EventHandler podczas wyzwalania zdarzenia zostanie opóźnione do momentu zakończenia wyzwalania zdarzenia. Jest to zgodne ze sposobem obsługi zdarzeń opartych na MulticastDelegate w środowisku uruchomieniowym wspólnego języka (CLR). Należy również pamiętać, że zdarzenia renderowania nie są wywoływane w żadnej określonej kolejności. Jeśli masz wielu EventHandler delegatów, które opierają się na określonej kolejności, należy zarejestrować jedno Rendering zdarzenie i multipleksować delegatów w odpowiedniej kolejności samodzielnie.

Zobacz także