RSS
 

Working With BackgroundWorker Part 2: Populating Treeviews

14 Apr

I ran into an issue the other day populating a Treeview with a bunch of data that took quite some time to retrieve. The problem wasn’t populating the tree, it was waiting for the data to come back, then populating the tree all at once that was bothering me. No one wants to wait forever for the treeview to become available. I figured a backgroundworker would be extremely useful at a time like this…

Let’s start by creating a simple method called PopulateTree and generating a BackgroundWorker… Make sure you generate the missing methods


private void PopulateTreeView()

{

BackgroundWorker bw = new BackgroundWorker();

bw.WorkerReportsProgress = true;

bw.WorkerSupportsCancellation = false;

bw.DoWork += new DoWorkEventHandler(bw_DoWork);

bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);

bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

You should already have a TreeView added to the Form. Lets just call it treeView1 for now. What we will do is populate the treeview with nodes 0 – a given number passed into the bw_DoWork method


//continuing inside the PopulateTreeView method

bw.RunWorkerAsync(10000);

}

//Now inside of our bw_DoWork method

void bw_DoWork(object sender, DoWorkEventArgs e)

{

//This is where the work you want the backgroundworker to do will be preformed

//DO NOT UPDATE THE GUI FROM HERE!

//The sender is the Background worker that called this Do Work

//Lets safely cast the backgroundwoker to bw

BackgroundWorker bw = sender as BackgroundWorker;

//The argument passed in is the number we want to count to.

int countTo = int.Parse(e.Argument.ToString());

//Loop through the numbers adding each one to the listview

for (int i = 1; i < countTo; i++)

{

//Calculate the percentage of numbers gone through

double percentComplete = (double) i / countTo) * 100;

//Report our progress

//This is where we tell the UI to update

//Lets pass the percentage and the number we want to add to the listview

bw.ReportProgress((int)percentComplete,i);

//Found it best to sleep for 1ms so the ui can update itself.

System.Threading.Thread.Sleep(1);

}

}

void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)

{

//This is where progress from the bw will be handled

//You CAN update the UI from this method.

int progressComplete = e.ProgressPercentage;

//this is the number to add to the TreeView

int number = (int)e.UserState;

treeView1.Nodes.Add(number.ToString());

}

So, basically what we did here was boxed up an int and sent it through background workers ReportProgress method and unboxed that number inside the ProgressChanged method, then added it to our listview.

This is the proper way to update the UI from a backgroundworker. What’s great is we are not limited to sending a single object through the report progress, we could send a collection or even any object through that… Part III will show an example of something more complex. This is a good start though.

Download Source BackgroundWorkers Populate Treeview

 
No Comments

Posted in C#, Threading

 

Tags: ,

Leave a Reply