Практическое руководство. Визуализация каждого кадра с помощью CompositionTarget
Подсистема анимации WPF предоставляет множество возможностей для создания анимации на основе кадров. Однако существуют сценарии приложений, в которых необходим детальный контроль отрисовки каждого кадра. CompositionTarget Предоставляет возможность создания пользовательской анимации на основе покадрового обратного вызова.
CompositionTarget является статическим классом, который представляет отображаемую поверхность, на котором рисуется приложение. Rendering Событие возникает каждый раз при рисовании сцены приложения. Частота кадров отрисовки — это количество отрисовок сцены за секунду.
Note
Пример полного кода с использованием CompositionTarget, см. в разделе пример использования CompositionTarget.
Пример
Rendering Событие запускается во время WPF процесс подготовки отчета. В следующем примере показано, как зарегистрировать EventHandler делегировать статического Rendering метод CompositionTarget.
// Add an event handler to update canvas background color just before it is rendered.
CompositionTarget.Rendering += UpdateColor;
Можно использовать собственный метод обработчика событий отрисовки для создания пользовательского графического содержимого. Метод обработчика событий вызывается один раз для каждого кадра. Каждый раз, когда WPF выполняет маршалинг сохраненных данных отрисовки в визуальном дереве через граф сцены композиции, вызывается метод обработчика событий. Кроме того, если изменения в визуальном дереве принудительно обновляют граф сцены композиции, метод обработчика событий также вызывается. Обратите внимание, что метод обработчика событий вызывается после вычисления макета. Однако можно изменить макет в методе обработчика событий, что означает повторное вычисление макета перед отрисовкой.
В следующем примере показано как можно реализовать пользовательское рисование CompositionTarget метод обработчика событий. В данном случае цвет фона Canvas рисуется пером значение цвета на основе координат положения указателя мыши. При перемещении указателя мыши внутри Canvas, ее изменения цвета фона. Кроме того вычисляется средняя частота кадров, на основе текущего значения прошедшего времени и общего числа отрисованных кадров.
// 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));
}
Может оказаться, что пользовательское рисование выполняется на разных компьютерах с разной скоростью. Это потому, что пользовательское рисование не является независимым от частоты кадров. В зависимости от используемой системы и рабочей нагрузки этой системы Rendering событие может вызываться Разное количество раз в секунду. Дополнительные сведения об определении возможностей графического оборудования и производительности для устройства, которое запускает приложение WPF см. в разделе Уровни отрисовки графики.
Добавление или удаление визуализации EventHandler делегата во время срабатывания события будет отложено до момента завершения события обработки. Это согласуется с тем, как MulticastDelegate-на основе события обрабатываются в Common Language Runtime (CLR). Также обратите внимание, что порядок вызова событий отрисовки не гарантируется. Если имеется несколько EventHandler делегаты, которые зависят от определенного порядка, необходимо зарегистрировать один Rendering событий и мультиплексировать делегаты в правильном порядке.