处理非常低的动画帧率

时间:2017-04-27 09:14:16

标签: c# wpf xaml animation directx

以下是该方案:

我有一系列主要包含列表框的视图。列表框,其中一些包含大量数据,一些非常少。 目前,我有一个附加行为,它基本上只是检测何时将新内容加载到这些视图的容器中(ContentPresenter)并触发一个简单的XAML故事板,将容器偏移200px到左边或者向右,并且还将不透明度降低到0%(0ms),然后超过100ms将不透明度恢复到100%并将偏移量减少回0px,从而创建一个“滑入视图”的视图。有点效果。

现在,问题是:

这个动画的帧率从平滑过渡到抖动,到完全只落后于1帧直到完成。 这几乎可以肯定是因为它必须加载新视图,渲染其中的所有内容,然后再进一步;其中包含大量数据的列表需要更多的渲染时间,然后所有发生的事情都会尝试动画其位置变化,这似乎会极大地影响动画的性能。

让我感到震惊的是,在屏幕上移动一些像素这样简单的事情对于WPF处理来说是图形密集型的

这里是动画本身的粗略表现: enter image description here

我的问题:

在WPF中处理密集动画是否存在任何基本的最佳实践,以便提高它们的性能,或者在添加提升性能时对事物进行任何小的改动? 或者WPF在制作动画时非常糟糕,我们只需处理它。

2 个答案:

答案 0 :(得分:0)

我认为你的问题是,你试图同时或同一个线程做所有事情。只是尝试在拆分任务中执行异步。有很多不同的方法。另一种方法是使用信号量来处理工作,这应该会使你的表现有所提升。

答案 1 :(得分:0)

我提出了一个解决方案,在我的情况下,它总能解决抖动问题。这当然值得一试。策略是采用在整个动画中不会改变的任何元素,将其插入本地参考框架(如网格或画布),使该网格或画布存储其内容的缓存版本,然后将动画应用于网格或画布,而不是内部元素。就这么简单:

<Canvas ...Your canvas properties...>
    <Canvas.CacheMode>
        <BitmapCache />
    </Canvas.CacheMode>
    ...Your UI elements...
</Canvas>

或者,对于网格:

<Grid ...Your grid properties...>
    <Grid.CacheMode>
        <BitmapCache />
    </Grid.CacheMode>
    ...Your UI elements...
</Grid>

您只想确保不更新画布(或网格)内的任何内容,因为这会撤消缓存版本,并且您会发现自己遇到类似的问题,WPF将重新生成其在每一帧上渲染。

通过内容的缓存版本,WPF将在屏幕上移动的内容不是动态更新的元素,它只是该元素最后渲染的位图,只有在应用更改时WPF才会更新该位图到元素。

如果这不能解决您的问题,则意味着在本地元素生成之外发生的事情会阻碍性能。这意味着您将要查看整个应用程序,或降低应用程序的整个帧速率。然而,在我发现的WPF动画的几乎所有抖动和抖动的情况下,BitmapCache解决方案似乎一直都在工作。请注意不要将动画应用于要缓存的元素内的对象。