I'm showing a print preview window for some large pages. The rendering of these takes some time so I want to show more progress information than the default 'Page 1/1' message.
I created a simple windows form project that shows my current approach:
(you can create a new windows form project with two forms and copy paste if you like)
public event EventHandler PrintReady;
public event ProgressChangedEventHandler ProgressChanged;
private void button1_Click(object sender, EventArgs e)
{
var printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
printDocument.EndPrint += new PrintEventHandler(printDocument_EndPrint);
var printPreviewDialog = new PrintPreviewDialog();
printPreviewDialog.Document = printDocument;
// Create the 'progress' form.
var form2 = new Form2(this);
form2.Show();
printPreviewDialog.ShowDialog();
}
void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
for (int i = 0; i < 100; i++)
{
// This is where I do some rendering.
Thread.Sleep(20);
if (this.ProgressChanged != null)
{
this.ProgressChanged.Invoke(this, new ProgressChangedEventArgs(i, null));
}
}
}
void printDocument_EndPrint(object sender, PrintEventArgs e)
{
if (this.PrintReady != null)
{
this.PrintReady.Invoke(this, null);
}
}
And then off course my progress form:
public Form2(Form1 form1)
{
form1.ProgressChanged += new ProgressChangedEventHandler(ProgressChangedHandler);
form1.PrintReady += new EventHandler(PrintReadyHandler);
InitializeComponent();
}
void PrintReadyHandler(object sender, EventArgs e)
{
this.Close();
}
void ProgressChangedHandler(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
The 'this.Close()' also closes my print preview! If I remove that line then the print preview is just shown and stays open. So the Close() function is closing both the progress window and the PrintPreview window.
Why is this happening?
I think you need to specify the owner of the Print Preview dialog as form1 - see below:
printPreviewDialog.ShowDialog(this);
Related
I encountered a weird issue that when I detach an MDIChild from its parent, the CurrencyManager PositionChanged event stops working. I got this behaviour in my main application and was able to reproduce it in a simple test app.
It's a WinForms App on .NET 4.8.
The Test App has Form1 as MDIParent and Form2 as an MDIChild. When starting the app, Form1 gets loaded and immediately initializes Form2 and assigns its MDIParent-Property to Form1.
Form1 also has a Button to Detach the currently active MDIChild so it can be moved independable.
public partial class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.MdiParent = this;
frm.Show();
}
private void btnDetachMDIChild_Click(object sender, EventArgs e)
{
if (ActiveMdiChild != null)
{
ActiveMdiChild.MdiParent = null;
}
}
}
Form2 has a DataTable with a CurrencyManager bound to it. The datatable is assigned to a datagridview for this example. When I click on a row in the datagridview, the cm_PositionChanged() event gets raised and the label on that form shows the current position of the CurrencyManager:
public partial class Form2 : Form
{
DataTable dt;
CurrencyManager cm;
private void Form2_Load(object sender, EventArgs e)
{
prepareTable();
fillTable();
cm.PositionChanged += new EventHandler(cm_PositionChanged);
}
private void cm_PositionChanged(object sender, EventArgs e)
{
lblPos.Text = cm.Position.ToString();
}
private void prepareTable()
{
dt = new DataTable();
dt.Columns.Add("Index", typeof(int));
cm = (CurrencyManager)this.BindingContext[dt];
dgv.DataSource = dt;
}
private void fillTable()
{
for (int i = 0; i < 100; i++)
{
dt.Rows.Add(i);
}
}
}
However, when I click on the "Detach MDI Child" button on Form1, Form2 gets detached, but the CurrencyManager doesn't work anymore. Apparently the event doesn't even get raised anymore.
I have no clue why this happens.. A wild guess is that this happens because the Form.Handle changes, but its just a gut feeling and I don't know how I would prevent this. Any ideas?
I found a solution/workaround that works for me:
Subscribing to the Form2.HandleCreated-Event, assigning a new BindingContext to the CurrencyManager and then resubscribing to the PositionChanged-Event. Also storing the current position for the users convenience:
private void Form2_Load(object sender, EventArgs e)
{
prepareTable();
fillTable();
cm.PositionChanged += new EventHandler(cm_PositionChanged);
this.HandleCreated += new EventHandler(Form2_HandleCreated);
}
private void Form2_HandleCreated(object sender, EventArgs e)
{
if (dt != null)
{
int pos = -1;
if (cm != null) { pos = cm.Position; }
cm = (CurrencyManager)this.BindingContext[dt];
cm.Position = pos;
cm.PositionChanged -= cm_PositionChanged;
cm.PositionChanged += new EventHandler(cm_PositionChanged);
}
}
I have a document printing function. I am trying to close the Print Preview Dialog form after the user presses the Print button. Once the print button in the print preview dialog is pressed, the event starts the function below to print the document. I am expecting the form to close when I call printPreviewDialog1.Close() but it just goes over the line and nothing happens.
But it doesn't close the print preview dialog form after the print job is done.
public void _start_Print(object sender, EventArgs e)
{
printDocument1.Print();
}
Added as requested in the comments. Initializing Print Preview Dialog
private void btnPrint_Click(object sender, EventArgs e)
{
PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
printPreviewDialog1.Document = printDocument1;
ToolStrip ts = new ToolStrip();
ts.Name = "wrongToolStrip";
foreach (Control ctl in printPreviewDialog1.Controls)
{
if (ctl.Name.Equals("toolStrip1"))
{
ts = ctl as ToolStrip;
break;
}
}
ToolStripButton printButton = new ToolStripButton();
ToolStripButton closeButton = new ToolStripButton();
foreach (ToolStripItem tsi in ts.Items)
{
if (tsi.Name.Equals("printToolStripButton"))
{
printButton = tsi as ToolStripButton;
}
else if (tsi.Name.Equals("closeToolStripButton")) // idk if this is the name of the close button im trying to programmatically close it after printing
{
closeButton = tsi as ToolStripButton;
}
}
ts.Items.Remove(printButton);
ToolStripButton b = new ToolStripButton();
b.ImageIndex = printButton.ImageIndex;
b.Visible = true;
ts.Items.Insert(0, b);
b.Click += new EventHandler(this._start_Print);
printPreviewDialog1.WindowState = FormWindowState.Maximized;
printPreviewDialog1.ShowDialog();
printPreviewDialog1.Dispose(); //< doesnt do anything
closeButton.PerformClick(); // < doesn't do anything, possibly using wrong name for toolstripbutton
}
Initializing Print Document as requested in the comments
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawRectange(Pens.Black, 60, 60, 60,60);
}
Solved.
I created a Global ToolStripButton and initialized this button with the closeToolStripButton in the printPreviewDialog.
Then I programmatically clicked this button after the print job was done.
private ToolStripButton closeButton = new ToolStripButton(); <-- global variable
private void btnPrint_Click(object sender, EventArgs e)
{
foreach (ToolStripItem tsi in ts.Items)
{
if (tsi.Name.Equals("closeToolStripButton"))
{
closeButton = tsi as ToolStripButton;
}
else if (tsi.Name.Equals("printToolStripButton"))
{
printButton = tsi as ToolStripButton;
}
}
ts.Items.Remove(printButton);
ToolStripButton b = new ToolStripButton();
b.ImageIndex = printButton.ImageIndex;
b.Visible = true;
ts.Items.Insert(0, b);
b.Click += new EventHandler(this._start_Printer); //<-- this starts the printer event where i "PerformClick() on the initialized closeButton"
printprevDialog.WindowState = FormWindowState.Maximized;
printprevDialog.ShowDialog();
}
public void _start_Printer(object sender, EventArgs e) // <--- then i just performed the close click here right after i hit the print button
{
printDocument1.Print();
closeButton.PerformClick(); // <-- this way im not violating cross thread operations
}
I am making a search utility and using a BackgroundWorker to search. I want that as soon as the first result is found , a new window should open up with a ListBox with the first element displayed. Now, I want that as soon as subsequent results are found, the ListBox should be updated with those results.
The method thought by me was to report the progress as soon as results are found and pass "New" and "Update" as userState to the method.
Based on the userState, I can decide whether to create a new Form or update and existing one.
Here is the code :-
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState.ToString() == "New")
{
Form ResultForm = new Form();
ResultForm.Name = "ResultForm" + i.ToString();
LastFormName = ResultForm.Name;
ListBox ResultListBox = new ListBox();
ResultListBox.DataSource = SearchList;
ResultListBox.Name = "ResultListBox" + i.ToString();
LastListName = ResultListBox.Name ;
ResultForm.Container.Add(ResultListBox);
ResultListBox.Show();
ResultForm.Show();
i++;
}
else
{
;
}
}
I have stored the names of the Last open Form and it's ListBox in the variables LastFormName and 'LastListName'.
I am unable to understand what to put in the else condition, so as to update the ListBox.
What I would do is expose some properties on the popup form so that you can tell if it is open and have access to the list box.
public partial class Popup : Form
{
public bool isOpen;
public ListBox PopupListBox;
public Popup()
{
InitializeComponent();
}
void Popup_FormClosing(object sender, FormClosingEventArgs e)
{
isOpen = false;
}
private void Popup_Load(object sender, EventArgs e)
{
this.FormClosing += Popup_FormClosing;
PopupListBox = popupListBox;
}
}
Then on the calling form I would subscribe to the ProcessedChanged Event and update the listbox with the data you are passing through the ProcessedChangedEventArgs. Here is the code for the calling form
public partial class Form1 : Form
{
Popup popupForm = new Popup();
BackgroundWorker backgroundWorker = new BackgroundWorker();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork += backgroundWorkerDoWork;
backgroundWorker.ProgressChanged += backgroundWorkerProgressChanged;
backgroundWorker.RunWorkerCompleted += backgroundWorkerRunWorkerCompleted;
}
void backgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
//What do you want to do if Cancelled?
}
else if (!(e.Error == null))
{
//What do you want to do if there is an error?
}
else
{
//What do you want to do when it is done?
}
}
void backgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (!popupForm.isOpen || popupForm == null)
{
popupForm = new Popup();
popupForm.Show();
popupForm.isOpen = true;
}
else
{
popupForm.Activate();
popupForm.WindowState = FormWindowState.Normal;
}
popupForm.PopupListBox.Items.Add(e.ProgressPercentage.ToString() + "%");
}
void backgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 1; (i <= 10); i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.ReportProgress((i * 10));
}
}
}
private void buttonStart_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy != true)
{
backgroundWorker.RunWorkerAsync();
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker.WorkerSupportsCancellation == true)
{
backgroundWorker.CancelAsync();
}
}
}
You shouldn't be doing work in the ProgressChanged event handler
You won't have access to the results as it is only passed an int for progress and user state
This is on the UI thread. The entire point is to do your processing on a background thread
The name DoWork event handler is clear that this is where you should do your processing.
In answer to your question. Since you create the ListBox in your event handler it goes out of scope outside the if statement. You need to create this in a more global scope. Then to add to it ResultListBox.Items.Add("ResultListBox" + i.ToString());
I don't have a thorough knowledge about controlling threads in c#. I want to create a progress bar while running a method.
I have two forms:
Form1 is the form which show up as you run the app. It has a button called btnScrape. When it is clicked the method should be called, the form with the progress bar should show up. Form1 should be disabled to the user until the progress bar is completed.
ProgressBarForm - this has the progress bar and a label.
The code is as follows.
//In Form1.cs I have a button.
private void btnScrape_Click(object sender, EventArgs e)
{
//gather data for folloeing parameters from the form.
Controller cntrlr = new Controller(urlFilePath, destinationPath, destinationfilename,cmbDepth.SelectedIndex);
cntrlr.Vmain(); // this is the method in controller class. while this is running i want show the progress bar.
}
// in Contrller class
class Controller{
List<string> urlList = null;
URLFileReader urlFileReader = null;
HTTPWorker httpWorker = null;
SourceReader srcreader = null;
ReportWriter reportWriter = null;
string urlFilePath, destinationPath, destinationFileName;
int depth;
public Controller(string urlFilePath,string destinationPath,string destinationFileName,int depth)
{
this.urlFilePath = urlFilePath;
this.destinationPath = destinationPath;
this.destinationFileName = destinationFileName;
this.urlList = new List<string>();
this.urlFileReader = new URLFileReader();
this.httpWorker = new HTTPWorker(this.destinationPath);
this.reportWriter = new ReportWriter(this.destinationPath,this.destinationFileName);
this.srcreader = new SourceReader(this.reportWriter);
this.depth = depth;
}
//this is the method
public void Vmain(){
this.urlFileReader.ReadURL(urlFilePath);
this.urlList = urlFileReader.geturlList();
string pageSrc;
foreach (string requestUrl in urlList)
{
//do sruff for requestUrl
//the progressbar should move as the urlList iterate.
//additionally i want the label on the top of progress bar to display the current "requestUrl"
//as the urlList is over i want quit from the progressbar window and come back to Form1. Till the progrss bar is completed Form1 should be disabled for the user.
}
}
}
Please explain what is happening there and give a working code if you can. Thank you in advance. There were not any perfect answer that worked for me, even though I spent two days for this. I tried with BackgroundWorkerand threads. But no solution found. :(
In the main form you could use this code:
private Progressfrm _loadForm;
private void ShowProgress()
{
ToggleForm();
_loadForm = new Progressfrm();
_loadForm.ShowDialog();
var tcheck = new Thread(CheckLoadedProgress);
tcheck.Start();
//do stuff here
}
private void CheckLoadedProgress()
{
while (_loadForm.IsAccessible) { }
ToggleForm();
}
private void ToggleForm()
{
Invoke(new Action(() => Enabled = !Enabled));
}
private void btnScrape_Click(object sender, EventArgs e)
{
var tform = new Thread(ShowProgress);
tform.Start();
}
Then the Progress-Form will appear until it is filled:
private ProgressBar _progressBar;
private void Progressfrm_Shown(object sender, EventArgs e)
{
_progressBar = new ProgressBar { Size = new Size(100, 20), Location = new Point(10, 10) };
Controls.Add(_progressBar);
_progressBar.Show();
Refresh();
LoadProgress();
}
private void LoadProgress()
{
while (_progressBar.Value < 100)
{
_progressBar.Value++;
Thread.Sleep(100);
}
Close();
}
On this Form you have to add the Event Shown and add the code like in my example. Hope this helps.
Use BackgroundWorker class to output progressBar and statusLabel changes:
BackgroundWorker bgw;
private void btnScrape_Click(object sender, EventArgs e)
{
bgw = new BackgroundWorker();
bgw.WorkerReportsProgress = true;
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.ProgressChanged += new ProgressChangedEventHandler(bgw_ProgressChanged);
bgw.RunWorkerAsync();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
Thread.Sleep(100);
bgw.ReportProgress(i);
}
}
private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
This is only an example how to update controls in an asynchron way.
my main problem is when i add dynamically a progressbar on flowLayoutPanel1 for each request then how can i increase right progressbar value frombackgroundWorker1_ProgressChanged event
when user click on start button then i will call RunWorkerAsync function of background worker....it is fine. here i am writing a sample code and try to show my problem.
my form has one textbox, one button and one flowLayoutPanel1 with FlowDirection topdown.
when user enter any url in textbox and click on start button then i will start file download with BackGroundWorker and add one progress bar dynamically on flowLayoutPanel1. 10 file can be downloaded at a time. so when user enter ten url one after after one and click on submit button then ten file will be downloading in background.
my problem is how to increment 10 progress bar progress properly from backgroundWorker1_ProgressChanged event another issue is when any file download will complete then the progress bar for which it has been created will be removed from panel
here is my full code. please have a look and tell me what i need to do to achieve my task. if anyone see there is problem in my code for which a dead lock may appear then also please guide me how to avoid dead lock. here is my code
public partial class Form1 : Form
{
static int pbCounter = 1;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
ProgressBar pb = new ProgressBar();
if (pbCounter <= 10)
{
pb.Width = txtUrl.Width;
flowLayoutPanel1.Controls.Add(pb);
pbCounter++;
System.ComponentModel.BackgroundWorker backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
System.ComponentModel.BackgroundWorker worker = sender as System.ComponentModel.BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
//#e.Result = ComputeFibonacci((int)e.Argument, worker, e);
}
// This event handler deals with the results of the
// background operation.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
//# "Canceled";
}
else
{
pbCounter--;
// Finally, handle the case where the operation
// succeeded.
//#resultLabel.Text = e.Result.ToString();
}
}
// This event handler updates the progress bar.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar1.Value = e.ProgressPercentage;
}
}
MY UPDATED PART
public partial class Form1 : Form
{
static int pbCounter = 1;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
ProgressBar pb = new ProgressBar();
if (pbCounter <= 10)
{
//pb.Step = 10;
pb.Minimum = 0;
//pb.Maximum = 100;
pb.Width = txtUrl.Width;
flowLayoutPanel1.Controls.Add(pb);
pbCounter++;
MyBackgroundWorker backgroundWorker1 = new MyBackgroundWorker();
backgroundWorker1.pbProgress = pb;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int input = int.Parse(e.Argument.ToString());
for (int i = 1; i <= input; i++)
{
Thread.Sleep(2000);
(sender as MyBackgroundWorker).ReportProgress(i * 10);
if ((sender as MyBackgroundWorker).CancellationPending)
{
e.Cancel = true;
return;
}
}
}
// This event handler deals with the results of the
// background operation.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
//# "Canceled";
}
else
{
ProgressBar pb = (sender as MyBackgroundWorker).pbProgress;
if (pb != null)
{
//pb.Value = 100;
//pb.Update();
while (pb.Value <= pb.Maximum)
{
//Thread.Sleep(1000);
flowLayoutPanel1.Controls.Remove(pb);
break;
}
}
// Finally, handle the case where the operation
// succeeded.
}
}
// This event handler updates the progress bar.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ProgressBar pb = (sender as MyBackgroundWorker).pbProgress;
pb.Refresh();
//if (e.ProgressPercentage < pb.Maximum)
// pb.Value = e.ProgressPercentage + 10;
pb.Value = e.ProgressPercentage ;
Application.DoEvents();
}
}
public class MyBackgroundWorker : System.ComponentModel.BackgroundWorker
{
public ProgressBar pbProgress = null;
public MyBackgroundWorker()
{
}
public MyBackgroundWorker(string name)
{
Name = name;
}
public string Name { get; set; }
}
This is one way of doing it -
Create your own class inherited from BackgroundWorker, Add a public variable of type ProgressBar.
Each time you add a BackgroundWorker and Progressbar dynamically, pass the progressbar object to your class.
Your derived Class -
public class MyBackgroundWorker : BackgroundWorker
{
public ProgressBar pbProgress = null;
public void BackgroundWorker()
{
}
}
Button Event Code -
private void btnStart_Click(object sender, EventArgs e)
{
ProgressBar pb = new ProgressBar();
if (pbCounter <= 10)
{
pb.Width = txtUrl.Width;
flowLayoutPanel1.Controls.Add(pb);
pbCounter++;
MyBackgroundWorker backgroundWorker1 = new MyBackgroundWorker();
backgroundWorker1.pbProgress = pb;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
}
}
Progress Changed Event -
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
(sender as MyBackgroundWorker).pbProgress.Value = e.ProgressPercentage;
}
First declare a global dictionary and a GetInstance Method to access the form instance
public partial class Form1 : Form
{
Dictionary<String, ProgressBar> progressBars = new Dictionary<String, ProgressBar>();
static Form1 _form1 = null;
static int pbCounter = 1;
public Form1()
{
InitializeComponent();
_form1 = this;
}
public static Form1 GetInstance() {
return _form1;
}
Then with each url you get and you must be creating pb for each of them, just add them in this dictionary too
progressBars.Add("file1", pb1);
progressBars.Add("file2", pb2);
progressBars.Add("file3", pb3);
progressBars.Add("file4", pb4);
Create a function in form.cs in which you can pass the progressbar and then you can manually set the value of it.
public void ProgessReport(ProgressBar pb, int value)
{
if (pb.InvokeRequired)
{
pb.Invoke(new MethodInvoker(delegate { ProgessReport(pb, value); }));
} else
{
pb.Value = value;
}
}
now from where you are downloading the file you just have to call
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file1"], 100);
and when your second file downloads then
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 10);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 20);
Form1.GetInstance().ProgessReport(Form1.GetInstance().progressBars["file2"], 100);
like this ..