22

我正在使用 WPF (C#) 的进度条来描述进程的进度。

我的算法如下:

DoSomethingCode1();
ProgressBar.SetPercent(10); // 10%
DoSomethingCode2();
ProgressBar.SetPercent(20); // 20%

...

DoSomethingCode10();
ProgressBar.SetPercent(100); // 100%

没关系,但它会使进度条不连续。

有人可以告诉我一些使进度条柔和更新的建议吗?

4

4 回答 4

42

你可以使用一个行为!

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您在 xaml 中绑定的属性发生更改时,ProgressBarSmoother 行为中的代码就会运行,并使用适当的值ToFrom!

于 2013-11-07T23:17:02.153 回答
21

您可以调用该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);

这样做只是平滑了过渡,因此看起来更好。引用另一个答案:“这个想法是进度条报告实际进度- 而不是经过的时间。它不打算成为仅指示正在发生的事情的动画。” 但是,进度条的默认样式确实具有脉动效果,这可能意味着工作正在发生。

于 2013-01-23T19:32:23.787 回答
3

检查您是否可以修改进度条的样式并为它的情节提要设置一个缓动功能,以修改进度条的“填充”,这样它就会有一个平滑的过渡。

于 2013-01-23T17:37:49.910 回答
-1

试试这个。

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();
        }
于 2013-10-04T08:05:25.977 回答