在一个WinForm窗体上有三个进度条(分别为a,b,c)和一个Button按钮,点击按钮,程序开始运行,当a走100%时,b走10%,c走1%。请问这个程序要怎么写?
首先你要对线程有一定的了解。进度条的显示、后台的进度计算是在两个线程里面分别来运行的。不然会出现不同步的问题。
然后是委托。用委托来进行两个线程之间的通信。
至于三个进度条,简单:直接在计算进度的线程中,算好的进度,直接给主线程a走100%时,b走10%,c走1%,百分知多少就是参数的问题。
如果你的重点是 “a走100%时,b走10%,c走1%”。你只要在得到百分比的算法上作文章了。
比如:a的工作量:循环100次,那么b循环1000次,c循环10000次。那么同等时间里就是你要的效果。
明白吧。这个功能在vs2005 中,有个控件是做个的。一个是那个进度条控件,一个就是 back..的控件。图标很好认有半个进度条。
给分吧
补充例子:
namespace Pro
{
delegate void setprogressBar(int prent, string rogressBar_name);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//声明委托对象
setprogressBar set = new setprogressBar(SetValue);
//进度条的计算、直接用循环代替后台的操作。
for (int i = 0; i < 10000; i++)
{
//跨线程调用
this.Invoke(set, new object[] { i / 100, "a" });
this.Invoke(set, new object[] { i / 1000, "b" });
this.Invoke(set, new object[] { i / 10000, "c" });
}
}
/// <summary>
/// 测试开始
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
this.backgroundWorker1.RunWorkerAsync();
}
/// <summary>
/// 主线程中设置进度数值
/// </summary>
/// <param name="prent">百分比</param>
/// <param name="name">控件名称</param>
private void SetValue(int prent, string name)
{
switch (name)
{
case "a":
this.progressBar1.Value = prent;
break;
case "b":
this.progressBar2.Value = prent;
break;
case "c":
this.progressBar3.Value = prent;
break;
}
}
}
}
页面拖拽控件代码省略。
设定主心跳 t int,可取时钟等。
a 取 t * 100 > 100 ? 100 : t * 100;
b 取 t * 10 > 100 ? 100 : t * 10;
c 取 t > 100 ? 100 : t;
搓吧,哈哈?
给三个控件设置Maximum时,按比例设置:
A:100
B:1000
C:10000
值溢出时归0.
呵呵,楼主貌似实际的程序应该不会你举的例子那样精确吧;
个人认为这三者不简单的数字关系,而是有很大的业务逻辑在里面,类似WINRAR的进度条,大不了用三个backgroundWorker 分别处理三个进度条;
由于时间仓促,给出简单实现,没有太多的考虑.本代码实现楼主要的效果.
1,三个 ProgressBar;
2,ProgressBar1 走 100 后通知 ProgressBar2 , ProgressBar1 Sleep 100 毫秒后重复该工作;
3,ProgressBar2 收到 ProgressBar1 的通知后走 10 ,然后通知 ProgressBar3,最后等待;
4,ProgressBar3 收到 ProgressBar2 的通知后 走 1 ,然后等待;
public class WorkerBar
{
private EventWaitHandle _event;
private EventWaitHandle _parentEvent;
private ProgressBar _bar;
public WorkerBar(ProgressBar bar,EventWaitHandle eventHandle,EventWaitHandle parentEventHandle)
{
this._bar = bar;
this._event = eventHandle;
this._parentEvent = parentEventHandle;
}
private delegate void PerformStepDelegate(ProgressBar progressBar);
public void PerformStep(ProgressBar progressBar)
{
if (!progressBar.InvokeRequired)
{
progressBar.PerformStep();
}
else
{
PerformStepDelegate performStep = new PerformStepDelegate(this.PerformStep);
progressBar.Invoke(performStep, new object[] { progressBar });
}
}
public EventWaitHandle Event
{
get
{
return this._event;
}
}
public EventWaitHandle ParentEvent
{
get
{
return this._parentEvent;
}
}
public ProgressBar Bar
{
get
{
return this._bar;
}
}
}
public partial class Form1 : Form
{
private List<WorkerBar> _workerBars;
private WaitHandle[] _waitEvents;
public Form1()
{
InitializeComponent();
_workerBars = new List<WorkerBar>();
_waitEvents = new WaitHandle[3];
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
_waitEvents[i] = new ManualResetEvent(false);
}
_workerBars.Add(new WorkerBar(this.progressBar1, (EventWaitHandle)_waitEvents[0], (EventWaitHandle)_waitEvents[1]));
_workerBars.Add(new WorkerBar(this.progressBar2, (EventWaitHandle)_waitEvents[1], (EventWaitHandle)_waitEvents[2]));
_workerBars.Add(new WorkerBar(this.progressBar3, (EventWaitHandle)_waitEvents[2], (EventWaitHandle)_waitEvents[0]));
Thread th1 = new Thread(ProgressBar1ThreadProc);
Thread th2 = new Thread(ProgressBar2ThreadProc);
Thread th3 = new Thread(ProgressBar3ThreadProc);
th1.Start(_workerBars[0]);
th2.Start(_workerBars[1]);
th3.Start(_workerBars[2]);
}
/// <summary>
/// 工作线程 1
/// </summary>
private static void ProgressBar1ThreadProc(object obj)
{
WorkerBar workerBar = (WorkerBar)obj;
while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
Thread.Sleep(100);
workerBar.PerformStep(workerBar.Bar);
workerBar.ParentEvent.Set(); //通知工作线程 1
}
}
/// <summary>
/// 工作线程 2
/// </summary>
private static void ProgressBar2ThreadProc(object obj)
{
WorkerBar workerBar = (WorkerBar)obj;
while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
workerBar.Event.WaitOne(); //等待工作线程 1 通知
workerBar.PerformStep(workerBar.Bar);
workerBar.Event.Reset();
workerBar.ParentEvent.Set(); //通知工作线程 3
}
}
/// <summary>
/// 工作线程 3
/// </summary>
private static void ProgressBar3ThreadProc(object obj)
{
WorkerBar workerBar = (WorkerBar)obj;
while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
workerBar.Event.WaitOne(); //等待工作线程 2 通知
workerBar.PerformStep(workerBar.Bar);
workerBar.Event.Reset();
}
}
}
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.progressBar2 = new System.Windows.Forms.ProgressBar();
this.progressBar3 = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(578, 42);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(12, 42);
this.progressBar1.Maximum = 1000;
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(533, 23);
this.progressBar1.Step = 100;
this.progressBar1.TabIndex = 1;
//
// progressBar2
//
this.progressBar2.Location = new System.Drawing.Point(12, 107);
this.progressBar2.Maximum = 1000;
this.progressBar2.Name = "progressBar2";
this.progressBar2.Size = new System.Drawing.Size(533, 23);
this.progressBar2.TabIndex = 1;
//
// progressBar3
//
this.progressBar3.Location = new System.Drawing.Point(12, 163);
this.progressBar3.Maximum = 1000;
this.progressBar3.Name = "progressBar3";
this.progressBar3.Size = new System.Drawing.Size(533, 23);
this.progressBar3.Step = 1;
this.progressBar3.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(689, 366);
this.Controls.Add(this.progressBar3);
this.Controls.Add(this.progressBar2);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.ProgressBar progressBar2;
private System.Windows.Forms.ProgressBar progressBar3;
}