[英]Programmatically scrolling a ScrollViewer with a timer becomes jerky
在ScrollViewer
動畫ScrollViewer
似乎是一項常見任務。 我使用計時器實現它,類似於此處的方法。 這種方法效果很好,非常流暢,看起來很完美。
但是,現在我的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
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.