进度条值与在windows 7中呈现的内容不同步
本文关键字:同步 windows | 更新日期: 2023-09-27 18:09:09
似乎在windows 7中,在设置进度条的值时发生了一些动画。设置值似乎不需要等待动画完成。是否有一种方法可以通知进度条何时完成动画?
我有一个示例程序。请看评论using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
namespace Testing
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form1();
form.Run();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Run()
{
Thread thread = new Thread
(
delegate()
{
ProgressBarMax = 10;
ProgressValue = 0;
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
ProgressValue++;
}
}
);
EventHandler show = delegate
{
thread.Start();
};
Shown += show;
ShowDialog();
Shown -= show;
}
public int ProgressBarMax
{
set
{
Invoke
(
(MethodInvoker)
delegate
{
progressBar1.Maximum = value;
}
);
}
}
public int ProgressValue
{
get
{
return progressBar1.Value;
}
set
{
Invoke
(
(MethodInvoker)
delegate
{
label1.Text = value.ToString();
progressBar1.Value = value;
// setting the value is not blocking until the
// animation is completed. it seems to queue
// the animation and as a result a sleep of 1 second
// will cause the animation to sync up with the UI
// thread.
// Thread.Sleep(1000); // this works but is an ugly hack
// i need to know if there is a callback to notify me
// when the progress bar has finished animating.
// then i can wait until that callback is handled
// before continuing.
// if not, do i just create my own progress bar?
}
);
}
}
}
}
我的google kung foo今天好像死了。谢谢。
最后,这与c#进度条与下载(WebClient类)不同步是相同的问题。
这个问题也类似于Windows窗体中的进度条很慢。这里的解决方案是向前和向后移动值,即progressBar1.Value = value + 1; progressBar1.Value = value;
。第一次更新开始动画序列,而第二次更新强制动画序列提前停止。这是一个很好的修复方法,但可能会引入难以复制的问题。这似乎没有一个真正的解决方案。
最后,在Vista Aero上禁用进度条动画建议关闭主题。这似乎是有效的,但进度条失去了它的外观和感觉。最后,最好的办法就是制作我自己的进度条。
微软应该让动画成为一个选项,而不是强迫开发人员重新发明进度条。
这个对我很有用:
if (progressBar1.Value <= progressBar1.Maximum - 2)
{
progressBar1.Value += 2;
progressBar1.Value--;
}
else if (progressBar1.Value <= progressBar1.Maximum)
{
progressBar1.Maximum--;
}
它更新进度条非常快,并负责最后一步,将其更新到100%。
多亏了LuisG的回答,我注意到ProgressBar中的"填充动画"仅在实际增加值时应用。
这允许我们在不使用几个条件的情况下利用它——我们只需要确保设置期望值的最后一次Value更新是一个减少Value的行为:
var tmp = progress.Maximum;
progress.Maximum = int.MaxValue;
progress.Value = int.MaxValue;
progress.Value = desiredValue;
progress.Maximum = tmp;
以上技巧之所以有效,是因为增加MAX和VALUE会触发动画,所以它不会立即渲染。然后我们立即减小这个值,这样就省略了(尚未执行的)动画并呈现新的状态。巧合的是,这正是我们一开始想要的状态。
以上技巧仅在desiredValue
小于int.MaxValue
时有效。如果您想要完整的整数范围,您必须使用LuisG的技巧来检测100%的最终情况并执行Maximum--
而不是提高值。