如何实现进度条动态更新?

leafsword_519 2008-06-18 09:35:26
现在需求是这样:
我有2个Form:FormMain,包含一个Button
FormProgress,包含一个ProgressBar

当我点击FromMain的button时,FormProgress以Dialog的方式弹出, 而且所包含的ProgressBar会随着FormMain中的处理逻辑动态显示进度

逻辑就如上,我应当如何做才能做到?

才接触Winform不久,还请多指教,谢谢!!!
...全文
774 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hesperus 2008-06-20
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 ddkc_c 的回复:]
肯定要用后台工作线程的,另外后台线程不能直接更新主线程的UI元素的状态,必须切换到主线程更新UI元素的状态,这个得靠委托来实现了:

控件上有四种方法可以从任何线程安全的调用:Invoke , BeginInvoke , EndInvoke,CreateGraphics
以下是异步回调的例子:
delegate void ShowProgressDelegate( int pos );

void ShowProcess( int pos )
{
if ( this.InvokeRequired == false )//确认在主线程上
{
proce…
[/Quote]

支持一下ddkc_c,回复得不错
czk598478 2008-06-20
  • 打赏
  • 举报
回复
楼主是星星级别的呢

?//
liujb526 2008-06-20
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 h_w_king 的回复:]
可以不用线程来完成.
private void button1_Click(object sender, EventArgs e)
{
Form2 ff = new Form2();
ff.Show();

for (int i = 0; i <= 100; i++)
{
ff.progressBar1.Value = i;
Application.DoEvents();
Thread.Sleep(100);
}
}

Form2里的progressBar1设…
[/Quote]

这个可以啊,我做过一个都是这样的哦
51Crack 2008-06-20
  • 打赏
  • 举报
回复
我以前做的在线程里ShowDialog后,父窗体还是能操作,真是怪了!
DalyQiao 2008-06-20
  • 打赏
  • 举报
回复
肯定要用后台工作线程的,另外后台线程不能直接更新主线程的UI元素的状态,必须切换到主线程更新UI元素的状态,这个得靠委托来实现了:

控件上有四种方法可以从任何线程安全的调用:Invoke , BeginInvoke , EndInvoke,CreateGraphics
以下是异步回调的例子:
delegate void ShowProgressDelegate( int pos );

void ShowProcess( int pos )
{
if ( this.InvokeRequired == false )//确认在主线程上
{
processbar.Value = pos;
}
else
{
ShowProgressDelegate showProgress = new ShowProgressDelegate( ShowProgress);
this.BeginInvoke(showProgress, new object[]{pos));
}

}

工作线程中调用此函数就行了

xinyun80 2008-06-20
  • 打赏
  • 举报
回复
以前做过一个感觉还可以: 用到了多线程和Timer控件
lalac 2008-06-20
  • 打赏
  • 举报
回复
我有一个n年前写的练习,从msdn上改的,或许刚好是lz要的效果:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace BackgroundWorkerExample
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
int arg = (int)e.Argument;
e.Result = CalculateSum(bw, arg);
if (bw.CancellationPending)
{
e.Cancel = true;
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.toolStripProgressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
this.toolStripStatusLabel1.Text = "Operation was canceled";
}
else if (e.Error != null)
{
string msg = String.Format("An error occurred: {0}", e.Error.Message);
this.toolStripStatusLabel1.Text = msg;
}
else
{
txtResult.Text = e.Result.ToString();
this.toolStripStatusLabel1.Text = "Finished successfully.";
}
this.toolStripProgressBar1.Value = 0;
}
private int CalculateSum(BackgroundWorker bw, int maxNum)
{
int result = 0;
for (int i = 0; i < maxNum; i++)
{
if (bw.CancellationPending) break;
result += i;
bw.ReportProgress((i * 100) / maxNum);
Thread.Sleep(500);
}
return result;
}
private void startBtn_Click(object sender, EventArgs e)
{
int number = 0;
if (int.TryParse(txtNumber.Text, out number))
{
this.toolStripStatusLabel1.Text = "Start calculating ...";
this.backgroundWorker1.RunWorkerAsync(number);
}
else
MessageBox.Show("Please input max number before calculating");
}
private void cancelBtn_Click(object sender, EventArgs e)
{
this.backgroundWorker1.CancelAsync();
}
private TextBox txtNumber;
private Label lblNumber;
private Label lblResult;
private TextBox txtResult;
private StatusStrip statusStrip1;
private ToolStripStatusLabel toolStripStatusLabel1;
private ToolStripProgressBar toolStripProgressBar1;
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
startBtn = new Button();
cancelBtn = new Button();
txtNumber = new TextBox();
lblNumber = new Label();
lblResult = new Label();
txtResult = new TextBox();
statusStrip1 = new StatusStrip();
toolStripStatusLabel1 = new ToolStripStatusLabel();
toolStripProgressBar1 = new ToolStripProgressBar();
statusStrip1.SuspendLayout();
SuspendLayout();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(this.backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
startBtn.Location = new Point(61, 75);
startBtn.Name = "startBtn";
startBtn.Size = new Size(75, 23);
startBtn.TabIndex = 0;
startBtn.Text = "Start";
startBtn.Click += new EventHandler(this.startBtn_Click);
cancelBtn.Location = new Point(161, 75);
cancelBtn.Name = "cancelBtn";
cancelBtn.Size = new Size(75, 23);
cancelBtn.TabIndex = 1;
cancelBtn.Text = "Cancel";
cancelBtn.Click += new EventHandler(this.cancelBtn_Click);
txtNumber.Location = new Point(113, 12);
txtNumber.Name = "txtNumber";
txtNumber.Size = new Size(148, 20);
txtNumber.TabIndex = 2;
lblNumber.AutoSize = true;
lblNumber.Location = new Point(40, 12);
lblNumber.Name = "lblNumber";
lblNumber.Size = new Size(67, 13);
lblNumber.TabIndex = 3;
lblNumber.Text = "Max Number";
lblResult.AutoSize = true;
lblResult.Location = new Point(40, 43);
lblResult.Name = "lblResult";
lblResult.Size = new Size(37, 13);
lblResult.TabIndex = 3;
lblResult.Text = "Result";
txtResult.Location = new Point(113, 40);
txtResult.Name = "txtResult";
txtResult.ReadOnly = true;
txtResult.Size = new Size(148, 20);
txtResult.TabIndex = 2;
statusStrip1.Items.AddRange(new ToolStripItem[] {
toolStripStatusLabel1,
toolStripProgressBar1});
statusStrip1.Location = new Point(0, 121);
statusStrip1.Name = "statusStrip1";
statusStrip1.Size = new Size(296, 22);
statusStrip1.TabIndex = 4;
statusStrip1.Text = "statusStrip1";
toolStripStatusLabel1.Name = "toolStripStatusLabel1";
toolStripStatusLabel1.Size = new Size(179, 17);
toolStripStatusLabel1.Spring = true;
toolStripStatusLabel1.Text = "Status";
toolStripStatusLabel1.TextAlign = ContentAlignment.MiddleLeft;
toolStripProgressBar1.Name = "toolStripProgressBar1";
toolStripProgressBar1.Size = new Size(100, 16);
toolStripProgressBar1.Step = 1;
AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(296, 143);
Controls.Add(this.statusStrip1);
Controls.Add(this.lblResult);
Controls.Add(this.lblNumber);
Controls.Add(this.txtResult);
Controls.Add(this.txtNumber);
Controls.Add(this.cancelBtn);
Controls.Add(this.startBtn);
FormBorderStyle = FormBorderStyle.FixedDialog;
Name = "Form1";
Text = "Calucate sum";
statusStrip1.ResumeLayout(false);
statusStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
private BackgroundWorker backgroundWorker1;
private Button startBtn;
private Button cancelBtn;
}
public class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
Adechen 2008-06-20
  • 打赏
  • 举报
回复
这种功能一般使用线程,通过委托调用来新进度
学习学习
pgdoryoku 2008-06-20
  • 打赏
  • 举报
回复
路过学习·····
帮顶~!
nnoovvee 2008-06-20
  • 打赏
  • 举报
回复
路过学习·····
帮顶~!
Jave.Lin 2008-06-19
  • 打赏
  • 举报
回复
作个标志...

学习学习...
家鸣 2008-06-19
  • 打赏
  • 举报
回复
两种方法:
1.就是3楼的通过委托调用来新进度。
2.通过API发送消息来更新进度。首先通过FindWindow/FindWindowEx组合找到ProgressBar的IntPtr,然后再用SendMessage or PostMessage发送消息更新进度。

WM_USER = 0x0400
SBM_SETRANGE = 0x00E;
PBM_SETPOS = (WM_USER + 2);
[DllImport("User32.dll",EntryPoint="FindWindow")]
private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);

[DllImport("user32.dll",EntryPoint="FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent,IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("User32.dll",EntryPoint="SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

[DllImport("User32.dll",EntryPoint="PostMessage")]
private static extern int PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

PostMessage(hWnd,SBM_SETRANGE,0,100); //设置进度条最小最大值
PostMessage(hWnd,PBM_SETPOS,25, 0);//设置进度。
HimeTale 2008-06-19
  • 打赏
  • 举报
回复
我比较喜欢通过事件来通知主线程
把处理数据的函数写到一个类中,这个类声明一个事件

每执行一次循环就触发一次事件。然后主线程响应,进度条前进一部分。
peterb 2008-06-19
  • 打赏
  • 举报
回复
http://blog.csdn.net/knight94/archive/2006/05/27/757351.aspx
冷月孤峰 2008-06-19
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20080528/16/fa79fde8-1a2d-4dc0-80d9-ca311be513a7.html
yagebu1983 2008-06-19
  • 打赏
  • 举报
回复
这东西一般就用线程做!!
帮你顶!!
nec_741 2008-06-19
  • 打赏
  • 举报
回复
shadowgreen 2008-06-19
  • 打赏
  • 举报
回复
路过学习·····
帮顶~!

h_w_king 2008-06-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 leafsword_519 的回复:]
我现在试过,如果以Progress.Show()方式打开窗体,那么进度条能正常显示

但是我如果以ShowDialog方式打开时,进度条就无法显示了
[/Quote]

如果这样的话:
Form2 ff = new Form2();
ff.ShowDialog();

for (int i = 0; i <= 100; i++)
{
ff.progressBar1.Value = i;
Application.DoEvents();
Thread.Sleep(100);
}
在执行完ff.ShowDialog();
程序等待ff的返回,然后再往下执行.
跟踪一下,在ff.ShowDialog()加断点,你就会发现在ff显示后,程序就不往下执行,至到你关闭ff后程序才往下执行.
wrxangeline 2008-06-19
  • 打赏
  • 举报
回复
学习学习 做个标记 很有用阿
加载更多回复(9)

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧