How to get an object to inform progress via a form's status bar?

S

sherifffruitfly

Hi,

I've got main() running in on a form. When a button on the form is
clicked, an object from a class I made is instantiated, and does some
stuff. I would like the stuff it does to be reflected in the form's
status bar. For example, "Now deleting file 35 of 234." if the object
was deleting a bunch of files.

I have no idea how to do this, but I understand there's some
thread-violation trickiness involved with having objects calling
controls on forms they don't own.

How can I achieve this effect easily/elegantly?

thanks for any ideas,

cdj
 
S

Simon Tamman

class Form1:Form
{

public delegate void StringDelegate(string message);

public void ThreadSafeUpdateText(string message)
{
this.BeginInvoke(new StringDelegate(UpdateText), new
object[]{message});
}

private void UpdateText(string message)
{
this.Text = message;
}
}

The above code will update the title of a given form without locking up in
thread hanging badness.

The Key is the BeginInvoke call. It basically queues the call onto the
WindowsMessagePump for the UI thread to handle (although that might be a
gross simplification, i'm not 100% sure).
A direct call to this.Text = "Whatever" would push ahead of the queue and
cause the threading issue by accessing the control on a different thread.

HTH

Simon Tamman
 
R

Rob Pollard

I like creating 2 sets of interfaces IProgressClient and IProgressServer.
The UI or its controller will implement the client whilst any classes
wishing to have the ability to write information to the progressbar
implement IProgressClient. I like this solution as it gives maximum
flexibility as to how you configure progress bars in your app and if done
right will allow the classes implementing the clients to still operate even
when there are no servers attached to them.

This is quite a woolly answer but should at least highlight the direction I
took. If needed I could probably dig up some source code...
 
S

sherifffruitfly

Simon Tamman wrote:

(code snipped)
The above code will update the title of a given form without locking up in
thread hanging badness.

I guess I just don't understand - it looks to my eye as though the
class (of the object) that's doing the stuff doesn't have any
"communication code" in your (and everyone else's) examples? How on
earth does the form know what's going on with the object, if the object
doesn't have any code "telling" the form what's going on?

I was probably unclear about what I'm dealing with. Here's a minimal
"template" example:

public class myform : system....form
{
..
..
..

private void btn_awesomeButton_Click(object sender, System.EventArgs e)
{
killerObject ko = new killerObject;
ko.doSomethingRockin();
}

}

public class killerObject
{
..
..
..

public doSomethingRockin()
{
(loop to delete 1000 hardcoded files here)
}

}

What I want to do is have the status bar (or any control) on the form
be updated every pass thru the loop in the object created by the button
click event (say with the name of the file being deleted).

Does that make sense even? Does your suggestion suffice for what I'm
after? I would've thought that some code would have had to have been
added to killerObject *as well as* to the form.

thanks for the replies all! sorry if I was unclear...
 
S

Simon Tamman

Well the code I presented displayed how the communication should operate
without encountering thready badness.
A more complete example would be:

class Form1:Form
{

public delegate void StringDelegate(string message);

public void ThreadSafeUpdateText(string message)
{
this.BeginInvoke(new StringDelegate(UpdateText), new
object[]{message});
}

private void UpdateText(string message)
{
this.Text = message;
}

private void btn_Click(object sender, EventArgs e)
{
KillerObject killer = new KillerObject(this);
killer.DoSomethingRockin();
}
}

public class KillerObject
{
Form1 form;
public KillerObject(Form1 form)
{
this.form = form;
}

public void DoSomethingRockin()
{
for(int i = 0; i< 100; i++)
{
form.ThreadSafeUpdateText("Currently looping: " + i.ToString());
}
}
}


Obviously you'd need to change the code to use a progress bar and it might
be better for the killer object to use events instead of taking a reference
to the form.
Additionally if you wanted to keep the UI active it would be best to run
"DoSomethingRockin" in a seperate thread.

HTH.

Simon Tamman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top