在 ScrollViewer
中设置滚动动画似乎是一项常见的任务。我使用计时器实现它,类似于找到的方法 here .这种方法效果很好,非常流畅,看起来很完美。
但是,现在我的 ScrollViewer
中包含的对象的复杂性和数量增加了,动画看起来非常不稳定。我觉得这很奇怪,因为如果我手动滚动它就可以正常工作。
public void ShiftLeft(int speed = 11)
{
CustomTimer timer = new CustomTimer(); //DispatchTimer with "life"
timer.Interval = new TimeSpan(0, 0, 0, 0, 5);
timer.Tick += ((sender, e) =>
{
scrollViewer1.ScrollToHorizontalOffset(
scrollViewer1.HorizontalOffset - (scrollViewer1.ScrollableWidth / (gridColumnCount - 3) / speed));
if (scrollViewer1.HorizontalOffset == 0) //cant scroll any more
((CustomTimer)sender).Stop();
((CustomTimer)sender).life++;
if (((CustomTimer)sender).life >= speed) //reached destination
((CustomTimer)sender).Stop();
});
timer.Start();
}
我的方法是否有问题导致这种奇怪的抽搐?知道如何解决吗?
最佳答案
CompositionTarget.Rendering
将更适合动画效果,因为它会在每次渲染帧时触发。尝试这样的事情:
public void Shift(ScrollViewer target, double speed = 11, double distance = 20)
{
double startOffset = target.HorizontalOffset;
double destinationOffset = target.HorizontalOffset + distance;
if (destinationOffset < 0)
{
destinationOffset = 0;
distance = target.HorizontalOffset;
}
if (destinationOffset > target.ScrollableWidth)
{
destinationOffset = target.ScrollableWidth;
distance = target.ScrollableWidth - target.HorizontalOffset;
}
double animationTime = distance / speed;
DateTime startTime = DateTime.Now;
EventHandler renderHandler = null;
renderHandler = (sender, args) =>
{
double elapsed = (DateTime.Now - startTime).TotalSeconds;
if (elapsed >= animationTime)
{
target.ScrollToHorizontalOffset(destinationOffset);
CompositionTarget.Rendering -= renderHandler;
}
target.ScrollToHorizontalOffset(startOffset + (elapsed * speed));
};
CompositionTarget.Rendering += renderHandler;
}
编辑:添加了范围检查
使用负距离值向左滚动。
编辑 2:
您可能希望使用此 CompositionTargetEx
实现而不是 CompositionTarget
,因为它只会在渲染线程实际绘制新帧时触发:
https://stackoverflow.com/a/16334423/612510
编辑 3:
由于您使用的是 WPF(而不是 Silverlight,就像我更习惯的那样),您可以使用 Stopwatch
类来测量经过的秒数,而不是我的 DateTime.Now
方法。
关于c# - 以编程方式滚动带有计时器的 ScrollViewer 变得不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17930481/