我正在使用 WPF (C#) 的进度条来描述进程的进度。
我的算法如下:
DoSomethingCode1();
ProgressBar.SetPercent(10); // 10%
DoSomethingCode2();
ProgressBar.SetPercent(20); // 20%
...
DoSomethingCode10();
ProgressBar.SetPercent(100); // 100%
可以,但会导致进度条不连贯。
有人能告诉我一些让进度条平滑更新的建议吗?
我正在使用 WPF (C#) 的进度条来描述进程的进度。
我的算法如下:
DoSomethingCode1();
ProgressBar.SetPercent(10); // 10%
DoSomethingCode2();
ProgressBar.SetPercent(20); // 20%
...
DoSomethingCode10();
ProgressBar.SetPercent(100); // 100%
可以,但会导致进度条不连贯。
有人能告诉我一些让进度条平滑更新的建议吗?
public class ProgressBarSmoother
{
public static double GetSmoothValue(DependencyObject obj)
{
return (double)obj.GetValue(SmoothValueProperty);
}
public static void SetSmoothValue(DependencyObject obj, double value)
{
obj.SetValue(SmoothValueProperty, value);
}
public static readonly DependencyProperty SmoothValueProperty =
DependencyProperty.RegisterAttached("SmoothValue", typeof(double), typeof(ProgressBarSmoother), new PropertyMetadata(0.0, changing));
private static void changing(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var anim = new DoubleAnimation((double)e.OldValue, (double)e.NewValue, new TimeSpan(0,0,0,0,250));
(d as ProgressBar).BeginAnimation(ProgressBar.ValueProperty, anim, HandoffBehavior.Compose);
}
}
您的XAML将如下所示:
<ProgressBar local:ProgressBarSmoother.SmoothValue="{Binding Progress}">
Progress
属性何时发生变化,ProgressBarSmoother行为中的代码都会运行,并使用适当的To
和From
值将动画添加到进度条中。请注意保留HTML标签。您可以调用BeginAnimation
方法来为ProgressBar
的Value
属性添加动画效果。在下面的示例中,我使用了一个DoubleAnimation
。
我创建了一个扩展方法,它接受所需的百分比:
public static class ProgressBarExtensions
{
private static TimeSpan duration = TimeSpan.FromSeconds(2);
public static void SetPercent(this ProgressBar progressBar, double percentage)
{
DoubleAnimation animation = new DoubleAnimation(percentage, duration);
progressBar.BeginAnimation(ProgressBar.ValueProperty, animation);
}
}
所以在你的代码中,你可以简单地调用:
myProgressBar.SetPercent(50);
这样做只是为了使过渡更加平滑,看起来更美观。引用另一个答案的话:“这种想法是进度条报告实际进度——而不是经过的时间。它不是旨在成为仅指示发生某些事情的动画。”然而,进度条的默认样式确实具有脉动效果,这可能暗示着正在进行工作。
请检查是否可以修改进度条的样式,并设置一个缓动函数到其故事板中,以修改进度条的“填充”,从而使其具有平滑的过渡效果。
试一下这个。
private void updateProgressBar(int percent)
{
if (ProgressBar.InvokeRequired)
{
updateProgressBarCallback cb = new updateProgressBarCallback(updateProgressBar);
this.Invoke(cb, new object[] { percent });
}
else
{
ProgressBar.Value = percent;
ProgressBar.Update();
ProgressBar.Refresh();
ProgressBar.Invalidate();
}