更改值时禁用.NET进度条动画?

ang*_*son 21 .net animation winforms progress-bar

我意识到关于动画和进度条的SO还有其他问题,但它们似乎围绕着摆脱进度条上绘制的动画,即.旅行的亮点.

我想要做的是摆脱我设置进度条的新值时使用的动画.我现在遇到的问题是正在运行的操作完成,然后进度条在操作完成继续增加到最大位置.

换句话说,如果我将进度条的Value属性设置为50,我希望它立即前进到中途位置(如果max是100),而不是像现在那样慢慢地将进度条建立到该位置.

如果确实有一个关于SO的问题已经处理过这个问题,那么关闭就像重复一样,我会高兴地删除它,但我找不到任何问题.

这是我发现的那个:禁用WinForms ProgressBar动画,它处理动画的高亮,这不是我所说的.

这是一个简单的LINQPad演示,它显示了这个问题:

void Main()
{
    using (var fm = new Form())
    {
        var bt = new Button
        {
            Text = "Start",
            Location = new Point(8, 8),
            Parent = fm,
        };
        var pb = new ProgressBar
        {
            Top = bt.Top + bt.Height + 8,
            Width = fm.ClientRectangle.Width - 16,
            Left = 8,
            Parent = fm
        };

        bt.Click += (s, e) =>
        {
            bt.Enabled = false;
            Thread t = new Thread(new ThreadStart(() =>
            {
                Thread.Sleep(1000);
                bt.BeginInvoke(new Action(() => { pb.Value = 50; }));
                Thread.Sleep(1000);
                bt.BeginInvoke(new Action(() => { pb.Value = 100; }));
                bt.BeginInvoke(new Action(() => { bt.Enabled = true; }));
            }));
            t.Start();
        };
        fm.ShowDialog();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑1:这是Windows 7,Glass主题,所以是的,我打赌这是特定于7或可能还有Vista.

这是一个显示问题的GIF动画,上面的项目.你可以看到,只要按钮变为启用,过半已定1秒后,中,动画进度达到100%,按钮已被启用.

如您所见,将按钮设置为启用并将进度条设置为100是"同时"完成的.基本上,我不希望逐步累积进度条,我希望它在按钮启用的同时直接跳到50%然后再跳到100%.

LINQPad演示


编辑2:回应David Heffernan的回答,这是我改变上述代码的方式:

bt.BeginInvoke(new Action(() => { pb.Value = 51; pb.Value = 50; }));
Thread.Sleep(1000);
bt.BeginInvoke(new Action(() => { pb.Maximum = 101; pb.Value = 101;
                                  pb.Maximum = 100; pb.Value = 100; }));
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 31

此动画功能是在Vista中引入的Aero主题.

但有一个解决方法.如果向后移动进度,则不会显示动画.因此,如果您希望它立即提前50,将值增加51,然后立即减1.

当接近100%时你会陷入冲突,因为你不能将Value设置为101(我假设Maximum设置为100).而是将Maximum设置为1000,例如,增加到1000,减少到999,然后再回到1000.

无论如何,它有点奇怪,但它确实有益于给你想要的效果!


Jon*_*art 15

这是我的扩展方法,基于David Heffernan建议:

把它包起来,将它隐藏起来,并假装它不存在!

public static class ExtensionMethods
{
    /// <summary>
    /// Sets the progress bar value, without using Windows Aero animation
    /// </summary>
    public static void SetProgressNoAnimation(this ProgressBar pb, int value)
    {
        // Don't redraw if nothing is changing.
        if (value == pb.Value)
            return;

        // To get around this animation, we need to move the progress bar backwards.
        if (value == pb.Maximum) {
            // Special case (can't set value > Maximum).
            pb.Value = value;           // Set the value
            pb.Value = value - 1;       // Move it backwards
        }
        else {
            pb.Value = value + 1;       // Move past
        }
        pb.Value = value;               // Move to correct value
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @sam您应该考虑学习以"快速失败"的方式编写代码.你可以用`if(value == pb.Value)返回来完成同样的事情,而不是堆积在缩进层上. (3认同)
  • 没爱?这是一个很好的建议. (2认同)