C# 为什么异步进度条上的文本会闪烁?
我想在C# 为什么异步进度条上的文本会闪烁?,c#,visual-studio-2012,asynchronous,progress-bar,C#,Visual Studio 2012,Asynchronous,Progress Bar,我想在ProgressBar上显示文本(而不必使用a)。这并不难做到,也不涉及OnPaint方法——如下面代码的按钮1所示。但是,此方法会阻止UI线程,而UI线程是。 不幸的是,我对异步方法的最佳尝试会导致文本闪烁,这非常烦人 有人能告诉我如何在不闪烁的情况下异步更新文本吗 (要运行以下代码,只需将其粘贴到新项目中即可 包含具有3个按钮和3个进度条的窗体) 使用系统; 使用系统图; 使用System.Windows.Forms; 使用System.Threading.Tasks; 使用系统线程;
ProgressBar
上显示文本(而不必使用a)。这并不难做到,也不涉及OnPaint
方法——如下面代码的按钮1所示。但是,此方法会阻止UI线程,而UI线程是。
不幸的是,我对异步方法的最佳尝试会导致文本闪烁,这非常烦人
有人能告诉我如何在不闪烁的情况下异步更新文本吗
(要运行以下代码,只需将其粘贴到新项目中即可
包含具有3个按钮和3个进度条的窗体)
使用系统;
使用系统图;
使用System.Windows.Forms;
使用System.Threading.Tasks;
使用系统线程;
namespace progbertest//相应地更改Program.cs中的名称空间
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
//此方法将阻止主UI线程
//(因此冻结了其他按钮)
启动日期(本协议第1条);
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
//这个方法(和下一个)不阻塞UI,可以同时使用,
//但是文本在闪烁
Task t=新任务(()=>StartUpdate(this.progressBar2));
t、 Start();
}
私有无效按钮3\u单击(对象发送者,事件参数e)
{
Task t=新任务(()=>StartUpdate(this.progressBar3));
t、 Start();
}
私有无效启动日期(ProgressBar progBar)
{
对于(int i=1;i可能是因为您正在从另一个线程绘制字符串。如果您可以使用基于控件的文本元素,则可以使用BeginInvoke,方式与ProgressBar相同:
// Label progressLbl
private void UpdateProgressFromAnotherThread(int completed, int total, string progressText)
{
this.progBar.BeginInvoke(new Action(() =>
{
this.progBar.Maximum = total;
this.progBar.Value = completed;
}));
this.progressLbl.BeginInvoke(new Action(() =>
{
this.progressLbl.Text = progressText;
}));
}
老实说,定制进度条是你最好的选择。如果你设置正确的话。我知道我没有回答你的问题,所以请不要投反对票,只是提供一个不同的解决方案。我还没有测试过这一点,但理论上它会在每次进度条重新绘制时得出百分比,每次值为他变了
您当前的问题是,每当您更改值时,该条都会重新绘制自身,因此文本会闪烁。如果它没有重新绘制,您将看到绘制的百分比开始相互重叠,这也不好
从设计角度来看,最好将所有内容封装在一个控件中
class CustomProgressBar : ProgressBar {
public CustomProgressBar() : base() {}
protected override void OnPaint(PaintEventArgs e) {
// Call the OnPaint method of the base class.
base.OnPaint(e);
string percentStr = this.Value.ToString() + "%";
PointF location = new PointF(this.Width / 2 - 10, this.Height / 2 - 7);
// Call methods of the System.Drawing.Graphics object.
e.Graphics.DrawString(percentStr, new Font("Arial",10), Brushes.Red, location );
}
}
谢谢。这是我的第一个策略,但我希望文本放在ProgressBar的顶部,但我找不到任何可以为ProgressLBL提供透明背景的方法。好的,那么也许你可以根据这个问题的答案尝试一些东西(如果你仍然不想创建自定义ProgressBar):谢谢,你可能是对的。但奇怪的是,我的方法在UI线程中运行良好,只在后台线程中闪烁。但我确实喜欢你的自定义progressbar简化版本(比我上面引用的公认答案中的版本简单得多)。我必须试一试
class CustomProgressBar : ProgressBar {
public CustomProgressBar() : base() {}
protected override void OnPaint(PaintEventArgs e) {
// Call the OnPaint method of the base class.
base.OnPaint(e);
string percentStr = this.Value.ToString() + "%";
PointF location = new PointF(this.Width / 2 - 10, this.Height / 2 - 7);
// Call methods of the System.Drawing.Graphics object.
e.Graphics.DrawString(percentStr, new Font("Arial",10), Brushes.Red, location );
}
}