以下是该方案:
我有一系列主要包含列表框的视图。列表框,其中一些包含大量数据,一些非常少。
目前,我有一个附加行为,它基本上只是检测何时将新内容加载到这些视图的容器中(ContentPresenter
)并触发一个简单的XAML故事板,将容器偏移200px到左边或者向右,并且还将不透明度降低到0%(0ms),然后超过100ms将不透明度恢复到100%并将偏移量减少回0px,从而创建一个“滑入视图”的视图。有点效果。
现在,问题是:
这个动画的帧率从平滑过渡到抖动,到完全只落后于1帧直到完成。 这几乎可以肯定是因为它必须加载新视图,渲染其中的所有内容,然后再进一步;其中包含大量数据的列表需要更多的渲染时间,然后所有发生的事情都会尝试动画其位置变化,这似乎会极大地影响动画的性能。
让我感到震惊的是,在屏幕上移动一些像素这样简单的事情对于WPF处理来说是图形密集型的
我的问题:
在WPF中处理密集动画是否存在任何基本的最佳实践,以便提高它们的性能,或者在添加提升性能时对事物进行任何小的改动? 或者WPF在制作动画时非常糟糕,我们只需处理它。
答案 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解决方案似乎一直都在工作。请注意不要将动画应用于要缓存的元素内的对象。