WPF中的动画不流畅

3
我在WPF中有一个动画,但是非常卡顿。我的WPF窗体布局如下:
一个1280x800的窗口包含一个2400x7**的网格,分成3列。
- 列1的宽度为* - 列2的宽度为148 - 列3的宽度为*
这使我能够使用动画将网格的边距更改为左侧约-1000,使左侧列不显示,将中间列移动到最右侧,然后在屏幕上滑动最右侧的列(类似于双页平移设计)。
这很不错,但当我将它们向左/右滑动时,我的屏幕组件以不同的速度运动。是否有一种方式可以对整个绘图空间进行双缓冲处理并一起滑动?或者这是否与WPF的本质相悖?

所以你正在对Margin属性进行动画处理?你能发布一下你的XAML代码,这样我就可以看到它是如何工作的吗? - Charlie
3个回答

4

另一种调查方法:

不使用XAML中的故事板,而是使用

CompositionTarget.Rendering

动画事件(根据经过的时间更改动画属性值)。可能需要在完成事件处理程序时结束。

thatBigGrid.UpdateLayout();

Margin(外边距)是一个影响布局的属性。在动画过程中改变网格的Margin时,Arrange函数将会被排队执行,在Arrange中每个Grid子元素的位置将会在循环中被更新。如果渲染下一帧在这个过程中开始,一些元素将在新位置中显示,一些则在旧位置中显示,从而造成卡顿。

如果确实出现了这种情况,解决方案是手动控制渲染事件,并确保在绘制前完全更新布局。


你能否更详细地解释一下这里正在发生什么,以使我和其他人受益? - Firoso

4
我已经检查过您的代码并确认了有趣的过渡效果。不过,只有向右转移时才会出现动画延迟。
当我将您的WebBrowser替换为一个有颜色的Border时,延迟问题就解决了。
所以结论是这里的问题是外部托管视觉元素的缓慢呈现。WebBrowser是一个Interop UI元素,继承自HwndHost
所以这绝对与XAML无关,我认为您必须接受当前的性能瓶颈。

好的,我很愿意听这个!我并没有真正期望一个Web控件 ^_^ - Firoso
我将其更改为椭圆形,但仍然看到了滞后 :-/ - Firoso
这确实是一个相当大的元素,逐点绘制可能会比较费时。建议尝试使用带有半径的边框代替。可以尝试用任何选项替换两侧内容。正如我所说的,这不是 XAML 的问题,WPF 渲染可能会变得有点慢。 - Kenan E. K.
嗯,WPF 是由 DirectX 驱动的,它应该自动进行双缓冲。 - Kenan E. K.

3
简单的缓冲并不能解决这个问题,因为似乎延迟不在于图形,而是在于动画期间更新不同元素属性的逻辑。以下方法应该有所帮助:
  • 点击按钮后,将整个网格渲染到RenderTargetBitmap中。
  • 在网格上方的某个矩形上绘制结果图像(RenderTargetBitmap继承自BitmapSource)。
  • 隐藏实际的网格。
  • 动画位图,将隐藏的网格移动到新位置
  • 显示网格
  • 隐藏位图
至于WPF的精神,它可以被称为必要的恶魔。你可以注意到,在滚动过程中,WPF本身的文本渲染会发生变化,例如 - 使用RenderTargetBitmap并没有更差。
免责声明:我没有尝试复制问题或阅读XAML,但上述方法自然避免了所有与矢量图形或托管元素相关的问题。

这是一个非常好的回答,虽然不完全符合我的期望,但它仍然回答了我的问题。此外,通过将显示元素渲染到缓存位图实现状态锁定并不完全不可能,因为在Windows 7中,窗口本身就经常使用这种方式来处理缩略图。 - Firoso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接