C# 进度条值与windows 7中呈现的内容不同步
似乎在Windows7中,设置进度条的值时会出现一些动画。设置该值似乎不会等待动画完成。是否有一种方法可以在进度条完成动画制作时收到通知 我有一个示例程序。请看评论C# 进度条值与windows 7中呈现的内容不同步,c#,winforms,progress-bar,C#,Winforms,Progress Bar,似乎在Windows7中,设置进度条的值时会出现一些动画。设置该值似乎不会等待动画完成。是否有一种方法可以在进度条完成动画制作时收到通知 我有一个示例程序。请看评论 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Threading; namespace Testing { static class Program
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?
}
);
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Windows.Forms;
使用系统线程;
命名空间测试
{
静态类程序
{
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form=new Form1();
form.Run();
}
}
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
公开募捐
{
线程=新线程
(
代表()
{
ProgressBarMax=10;
ProgressValue=0;
对于(int i=0;i<10;i++)
{
睡眠(1000);
ProgressValue++;
}
}
);
EventHandler show=委托
{
thread.Start();
};
显示+=显示;
ShowDialog();
显示-=显示;
}
公共int ProgressBarMax
{
设置
{
援引
(
(MethodInvoker)
代表
{
progressBar1.最大值=数值;
}
);
}
}
公共价值
{
得到
{
返回progressBar1.值;
}
设置
{
援引
(
(MethodInvoker)
代表
{
label1.Text=value.ToString();
progressBar1.值=值;
//直到
//动画已完成。它似乎正在排队
//动画,因此睡眠时间为1秒
//将导致动画与UI同步
//线。
//Thread.Sleep(1000);//这个方法有效,但它是一个丑陋的黑客
//我需要知道是否有回电通知我
//进度条完成动画制作后。
//然后我可以等到回调处理完毕
//在继续之前。
//如果没有,我是否只创建自己的进度条?
}
);
}
}
}
}
我的谷歌功夫今天好像死了。谢谢。归根结底,这是与您相同的问题 这个问题也类似于。这里的解决方案是前后移动值,即
progressBar1.value=value+1;progressBar1.值=值代码>。第一次更新开始动画序列,而第二次更新强制动画序列提前停止。这是一个很好的解决方案,但会带来难以重现的问题。似乎没有真正的解决办法
最后,建议关闭主题。这似乎有效,但进度条失去了它的外观和感觉。最终,最好的办法就是让自己进步吧
微软应该让动画成为一种选择,而不是强迫开发者重新发明进度条。最后,这与我们的问题是一样的
这个问题也类似于。这里的解决方案是前后移动值,即progressBar1.value=value+1;progressBar1.值=值代码>。第一次更新开始动画序列,而第二次更新强制动画序列提前停止。这是一个很好的解决方案,但会带来难以重现的问题。似乎没有真正的解决办法
最后,建议关闭主题。这似乎有效,但进度条失去了它的外观和感觉。最终,最好的办法就是让自己进步吧
微软应该让动画成为一种选择,而不是强迫开发者重新发明进度条。这为我带来了窍门:
if (progressBar1.Value <= progressBar1.Maximum - 2)
{
progressBar1.Value += 2;
progressBar1.Value--;
}
else if (progressBar1.Value <= progressBar1.Maximum)
{
progressBar1.Maximum--;
}
if(progressBar1.Value这为我带来了好处:
if (progressBar1.Value <= progressBar1.Maximum - 2)
{
progressBar1.Value += 2;
progressBar1.Value--;
}
else if (progressBar1.Value <= progressBar1.Maximum)
{
progressBar1.Maximum--;
}
if(progressBar1.Value多亏了LuisG的回答,我注意到ProgressBar中的“填充动画”只有在实际增加值时才被应用。当减少值时,动画不会被使用,并且栏会立即更新
这允许我们在不使用几个条件的情况下利用它-我们只需要确保设置所需值的最后一次值更新是一个降低值的行为:
var tmp = progress.Maximum;
progress.Maximum = int.MaxValue;
progress.Value = int.MaxValue;
progress.Value = desiredValue;
progress.Maximum = tmp;
上述技巧之所以有效,是因为增加“最大值”和“值”会触发动画,因此不会立即渲染。然后我们立即减少该值,这会忽略(尚未执行)动画并渲染新状态。巧合的是,这正是我们首先想要的状态
上述技巧仅在desiredValue
小于int.MaxValue
时有效。如果您想要完整的整数范围,则必须使用LuisG的技巧,检测100%的最终情况并执行最大值--
,而不是提高值。感谢LuisG的回答,我注意到仅当实际增加值时,ProgressBar中的“填充动画”才会启用。减少值时,不使用动画,并立即更新栏
这允许我们在不使用几个条件的情况下利用它-我们只需要确保设置所需值的最后一次值更新是一个降低值的行为:
var tmp = progress.Maximum;
progress.Maximum = int.MaxValue;
progress.Value = int.MaxValue;
progress.Value = desiredValue;
progress.Maximum = tmp;
上述技巧之所以有效,是因为增加“最大值”和“值”会触发动画,