I've spent 4 hours on this and totally failed. I know that i need to use BackgroundWorker but all the tutorials refer to running a progress script on the actual form you are running the worker on.
I have a large datagrid, which the user can use a check box to "select all" and then press "UPDATE ALL" This updates every grid with a bunch of options they choose. For some users this may be 5 records which is nothing, but some might update 200 records with 5 options which takes about... 10-15 secs to iterate through them.
I have tried so many variations of running BGworker which loads a FrmLoading.Showdialog
Or trying to have BGworker "do work" running the code and then the main thread having the FrmLoading.Show() However nothing is working.
If i have the update code in the background worker, it fails because the datagrid and everything is in a different thread.
The other way round, and it just hangs on FrmLoading.Show()
Any advice would be great.
I just can't seem to get my head around how to get this working for what seems to be an easy idea!
Current Update Code:
foreach (DataGridViewRow rowx in dataGridpatients.Rows)
{
//MessageBox.Show(Convert.ToBoolean(rowx.Cells["clnselected"].Value).ToString());
if (Convert.ToBoolean(rowx.Cells["clnselected"].Value) == true)
{
//if cycle has a value.
if (cmbcycle.SelectedIndex != -1)
{
rowx.Cells["clncycletype"].Value = cycle;
rowx.Cells["clnpackscollect"].Value = packs;
}
//if location has a value
if (cmblocation.SelectedIndex != -1)
{
location = Convert.ToInt32(cmblocation.SelectedValue);
rowx.Cells["clnlocation1"].Value = location;
}
if (cmbsize.SelectedIndex != -1)
{
size = Convert.ToInt32(cmbsize.SelectedValue);
rowx.Cells["clnpacksize"].Value = size;
}
if (chkDelivery.Checked == true)
{
rowx.Cells["clnDelivery"].Value = true;
}
if (chkSignSheet.Checked == true)
{
rowx.Cells["clnSigningSheet"].Value = true;
}
}
countupdated++;
}
foreach (DataGridViewRow row in dataGridpatients.Rows)
{
row.Cells["clnselected"].Value = false;
row.DefaultCellStyle.BackColor = Color.White;
}
cmbsize.SelectedIndex = -1;
cmblocation.SelectedIndex = -1;
cmbcycle.SelectedIndex = -1;
chkDelivery.Checked = false;
chkSignSheet.Checked = false;
@countupdated++;
I also have @CountSelected.
What i want to do is run this code above but have a popup overlay (dialog) with my logo + "Updating X%" Where X = countupdated/countselected * 100
I now know i need to use the background worker and invoke for the above, but literally have no idea regarding how to invoke the grid and go from there. I understand i need to invoke the variables I'm using (eg. cmbcycle.SelectedIndex)
I know iterating through 150 records and updating individual cells is probably wrong,
My other option is creating a datatable from "selected" cells on that datatable then Running the update via SQL instead of iterating through a bound table. Then after the SQL i can re-create the table which will now have the new cell values updated in it? Would that be a more appropriate way to do it?
Max rows on this table would be 200. Average ~70 so we are never talking 500 or 1000
EDIT: So the checked answer works to run the background worker and refer to the controls on the form. The issue is that if i do this:
backgroundWorker1.RunWorkerAsync();
splashy.ShowDialog();
Then the splash screen pops up after the background worker ends
If i do this:
splashy.ShowDialog();
backgroundWorker1.RunWorkerAsync();
Then the popup semi-forms and hangs until the end of the background worker, at which time it closes because of the RunWorkerCompleted event.
EDIT: I have no updated the code in DoWork and used Invokes to refer to the controls. This works and the code runs fine.
I now need a popup ot appear showing the progress through the updates.
splashy.InvokeBy(() =>
{
splashy.Show();
});
backgroundWorker1.RunWorkerAsync();
Does not work. It causes the popup but freeze
splashy.ShowDialog();
backgroundWorker1.RunWorkerAsync();
Allows the Dialog to show (not 'frozen' and distorted) However the Lab (lblprogress) does not update.
This is because the form never get to the RunWorker method, it is stuck at ShowDialog.