Hi All,
I'm a newbee in C# and have a Windows form application. The main form
has a progress bar. In one of the methods of the main form, I call a
class derived from Object which processes a file. During the
processing, I'd like the custom class to be able to update the
progress bar.
What's the best way to make this happen? I've been reading up on
events/delegates and am beginning to get a vague understanding, but I
wanted to make sure I'm not going down the wrong path.
Thanks for any suggestions/insight,
Steve 12 1356
Hi,
"Steve" <ki****@harpservices.comwrote in message
news:iv********************************@4ax.com...
Hi All,
I'm a newbee in C# and have a Windows form application. The main form
has a progress bar. In one of the methods of the main form, I call a
class derived from Object which processes a file. During the
processing, I'd like the custom class to be able to update the
progress bar.
What's the best way to make this happen? I've been reading up on
events/delegates and am beginning to get a vague understanding, but I
wanted to make sure I'm not going down the wrong path.
You have to use a thread to perform the operation and in the meantime in the
UI thread the progress bar is running.
Take a look at Control.Invoke as the way to communication between the worker
thread and the UI
On Thu, 13 Sep 2007 21:36:25 +0200, Steve <ki****@harpservices.comwrote:
Hi All,
I'm a newbee in C# and have a Windows form application. The main form
has a progress bar. In one of the methods of the main form, I call a
class derived from Object which processes a file. During the
processing, I'd like the custom class to be able to update the
progress bar.
What's the best way to make this happen? I've been reading up on
events/delegates and am beginning to get a vague understanding, but I
wanted to make sure I'm not going down the wrong path.
Thanks for any suggestions/insight,
Steve
Hi Steve
An event should work fine here, but you also need to start your processing in a BackgroundWorker or another thread or the main thread won't get time to process the event. And since the event will get caught in a thread other than the main thread, you need to use Invoke as well. The sample below might give you some ideas. If you don't mind having the classcall the form directly (which isn't really good OO practice, you can skip throwing the event and call the form directly)
public class MyForm : Form
{
<...>
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
MyClass myClass = new MyClass();
private void Method()
{
myClass.MyEvent += new MyClass.MyEventHandler(myClass_MyEvent);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCom pleted);
worker.RunWorkerAsync();
}
void myClass_MyEvent(int value)
{
if (progressBar1.InvokeRequired)
progressBar1.Invoke(new ProgressBarDelegate(myClass_MyEvent), new object[] { value });
else
progressBar1.Value = value / 2;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
myClass.Method();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
}
public class MyClass
{
public event MyEventHandler MyEvent;
public delegate void MyEventHandler(int value);
public void Method()
{
for (int i = 0; i < 200; i++)
{
System.Threading.Thread.Sleep(200);
MyEvent(i);
}
}
}
--
Happy coding!
Morten Wennevik [C# MVP]
On Thu, 13 Sep 2007 16:05:20 -0400, "Ignacio Machin \( .NET/ C# MVP
\)" <machin TA laceupsolutions.comwrote:
>Hi,
"Steve" <ki****@harpservices.comwrote in message news:iv********************************@4ax.com.. .
>Hi All,
I'm a newbee in C# and have a Windows form application. The main form has a progress bar. In one of the methods of the main form, I call a class derived from Object which processes a file. During the processing, I'd like the custom class to be able to update the progress bar.
What's the best way to make this happen? I've been reading up on events/delegates and am beginning to get a vague understanding, but I wanted to make sure I'm not going down the wrong path.
You have to use a thread to perform the operation and in the meantime in the UI thread the progress bar is running. Take a look at Control.Invoke as the way to communication between the worker thread and the UI
I'd like to avoid multi-threading if I can. I have no experience in
managing threads and it doesn't seem like it should be that
complicated to just reference a component on a form.
Hi,
"Steve" <ki****@harpservices.comwrote in message
news:mb********************************@4ax.com...
On Thu, 13 Sep 2007 16:05:20 -0400, "Ignacio Machin \( .NET/ C# MVP
\)" <machin TA laceupsolutions.comwrote:
>>Hi,
"Steve" <ki****@harpservices.comwrote in message news:iv********************************@4ax.com. ..
>>Hi All,
I'm a newbee in C# and have a Windows form application. The main form has a progress bar. In one of the methods of the main form, I call a class derived from Object which processes a file. During the processing, I'd like the custom class to be able to update the progress bar.
What's the best way to make this happen? I've been reading up on events/delegates and am beginning to get a vague understanding, but I wanted to make sure I'm not going down the wrong path.
You have to use a thread to perform the operation and in the meantime in the UI thread the progress bar is running. Take a look at Control.Invoke as the way to communication between the worker thread and the UI
I'd like to avoid multi-threading if I can. I have no experience in
managing threads and it doesn't seem like it should be that
complicated to just reference a component on a form.
It's not complicated, besides if you never start you will never learn :)
See the other post in this thread as well as in the archives, a solution to
your problem is posted or discussed at least once a week
"Morten Wennevik [C# MVP]" wrote:
On Thu, 13 Sep 2007 21:36:25 +0200, Steve <ki****@harpservices.comwrote:
Hi All,
I'm a newbee in C# and have a Windows form application. The main form
has a progress bar. In one of the methods of the main form, I call a
class derived from Object which processes a file. During the
processing, I'd like the custom class to be able to update the
progress bar.
What's the best way to make this happen? I've been reading up on
events/delegates and am beginning to get a vague understanding, but I
wanted to make sure I'm not going down the wrong path.
Thanks for any suggestions/insight,
Steve
Hi Steve
An event should work fine here, but you also need to start your processing in a BackgroundWorker or another thread or the main thread won't get time to process the event. And since the event will get caught in a thread other than the main thread, you need to use Invoke as well. The sample below might give you some ideas. If you don't mind having the class call the form directly (which isn't really good OO practice, you can skip throwing the event and call the form directly)
public class MyForm : Form
{
<...>
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
MyClass myClass = new MyClass();
private void Method()
{
myClass.MyEvent += new MyClass.MyEventHandler(myClass_MyEvent);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCom pleted);
worker.RunWorkerAsync();
}
void myClass_MyEvent(int value)
{
if (progressBar1.InvokeRequired)
progressBar1.Invoke(new ProgressBarDelegate(myClass_MyEvent), new object[] { value });
else
progressBar1.Value = value / 2;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
myClass.Method();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
}
public class MyClass
{
public event MyEventHandler MyEvent;
public delegate void MyEventHandler(int value);
public void Method()
{
for (int i = 0; i < 200; i++)
{
System.Threading.Thread.Sleep(200);
MyEvent(i);
}
}
}
--
Happy coding!
Morten Wennevik [C# MVP]
Hi Morten,
Thanks for the reply very useful. The only problem I get whilst running that
code is when I get to the MyEvent(i); call in public void Method() I get a
NullReferenceException with "Object reference not set to an instance of an
object". Any idea what I'm doing wrong?
Cheers,
Andy
That means that nobody is listening to your event; a minor nuicance,
but you need to check events for null; this is usually done in an "On"
method, i.e. (given your unusual event signature):
protected virtual void OnMyEvent(int value) {
MyEventHandler handler = MyEvent;
if(handler!=null) handler(value);
}
and then call OnMyEvent(i); instead of MyEvent(i);
For a lazy implementation, you could just use:
if(MyEvent!=null) {MyEvent(i);}
but there are a few subtle issues that make the OnMyEvent the
recommended approach.
Marc
"Marc Gravell" wrote:
That means that nobody is listening to your event; a minor nuicance,
but you need to check events for null; this is usually done in an "On"
method, i.e. (given your unusual event signature):
protected virtual void OnMyEvent(int value) {
MyEventHandler handler = MyEvent;
if(handler!=null) handler(value);
}
and then call OnMyEvent(i); instead of MyEvent(i);
For a lazy implementation, you could just use:
if(MyEvent!=null) {MyEvent(i);}
but there are a few subtle issues that make the OnMyEvent the
recommended approach.
Marc
Hi Marc,
Thanks for the reply - I'm obviously not doing something right;
In my form I have:-
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
TryClass myClass = new TryClass();
private void Method()
{
myClass.MyEvent += new TryClass.MyEventHandler(myClass_MyEvent);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(worker_RunWorkerCom pleted);
worker.RunWorkerAsync();
}
void myClass_MyEvent(int value)
{
if (prgStatus.InvokeRequired)
prgStatus.Invoke(new ProgressBarDelegate(myClass_MyEvent),
new object[] { value });
else
prgStatus.Value = value / 2;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
myClass.Method();
}
void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
In the class I have :-
public event MyEventHandler MyEvent;
public delegate void MyEventHandler(int value);
public void Method()
{
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(200);
if (MyEvent != null)
{ MyEvent(i); }
}
}
I am then calling the method from another class in the same project;
TryClass x = new TryClass ();
x.Method();
All I seem to get are null values in the MyEvent(i) - any ideas what I am
doing wrong? It's like the MyEvent doesn't connect back to the form.
Thanks,
Andy
All I seem to get are null values in the MyEvent(i)
Sorry - can you clarify what you mean? is MyEvent null? Or is
something throwing an exception?
Note that with BackgroundWorker, a better way to handle the updates is
to set WorkerReportsProgress = true, and then from your loop call
ReportProgress(value). You can then catch the ProgressChanged event
(which is fired on the UI thread, so no InvokeRequired / Invoke) and
get the value from the event-arg.
Marc
Andy C wrote:
Thanks for the reply - I'm obviously not doing something right;
Correct. :)
In my form I have:-
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
TryClass myClass = new TryClass();
So, in your form, you've created an instance of TryClass() and subscribe
your event handler to the event in that instance.
[...]
I am then calling the method from another class in the same project;
TryClass x = new TryClass ();
And then within your background worker thread, you create a new instance
of TryClass().
x.Method();
And then call the method that raises the event using that new instance,
rather than the instance in which you subscribed your handler.
All I seem to get are null values in the MyEvent(i) - any ideas what I am
doing wrong? It's like the MyEvent doesn't connect back to the form.
You are creating a new instance of TryClass. That instance is not the
same one to which you subscribed your event handler, so of course the
event in that instance isn't subscribed.
You need to create just one instance of the class, and then use that
instance when executing the method of interest. Alternatively (and this
comes up more often than one might think) if you can genuinely get away
with creating a new instance each time you want to call the method, then
that method shouldn't be an instance method anyway as you're obviously
not using anything that is unique per-instance.
In this alternative case, just make the method and the event static.
And of course, if you have no other instance members in the class, then
the class itself could be static.
Pete
"Peter Duniho" wrote:
Andy C wrote:
Thanks for the reply - I'm obviously not doing something right;
Correct. :)
In my form I have:-
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
TryClass myClass = new TryClass();
So, in your form, you've created an instance of TryClass() and subscribe
your event handler to the event in that instance.
[...]
I am then calling the method from another class in the same project;
TryClass x = new TryClass ();
And then within your background worker thread, you create a new instance
of TryClass().
x.Method();
And then call the method that raises the event using that new instance,
rather than the instance in which you subscribed your handler.
All I seem to get are null values in the MyEvent(i) - any ideas what I am
doing wrong? It's like the MyEvent doesn't connect back to the form.
You are creating a new instance of TryClass. That instance is not the
same one to which you subscribed your event handler, so of course the
event in that instance isn't subscribed.
You need to create just one instance of the class, and then use that
instance when executing the method of interest. Alternatively (and this
comes up more often than one might think) if you can genuinely get away
with creating a new instance each time you want to call the method, then
that method shouldn't be an instance method anyway as you're obviously
not using anything that is unique per-instance.
In this alternative case, just make the method and the event static.
And of course, if you have no other instance members in the class, then
the class itself could be static.
Pete
Hi Peter,
Thanks for the reply - I think I'm nearly there now. I made the class static
but I'm still getting nothing but null values.
In the class I have;
public static class TryClass
{
public static event MyEventHandler MyEvent;
public delegate void MyEventHandler(int value);
public static void Method()
{
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(200);
if (MyEvent != null)
{ MyEvent(i); }
}
}
In the form I have;
delegate void ProgressBarDelegate(int value);
BackgroundWorker worker = new BackgroundWorker();
private void Method()
{
TryClass.MyEvent += new TryClass.MyEventHandler(TryClass_MyEvent);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(worker_RunWorkerCom pleted);
worker.RunWorkerAsync();
}
void TryClass_MyEvent(int value)
{
if (prgStatus.InvokeRequired)
prgStatus.Invoke(new ProgressBarDelegate(TryClass_MyEvent),
new object[] { value });
else
prgStatus.Value = value / 2;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
TryClass.Method();
}
void worker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Done");
}
I'm now calling TryClass.Method(); and I'm still getting nothing but null
values.
Thanks,
Andrew
Andy C wrote:
[...]
I'm now calling TryClass.Method(); and I'm still getting nothing but null
values.
Well, maybe I'm just overlooking something, but I didn't see anything
obviously wrong in the code you posted (other than the fact that you
don't unsubscribe from the event after you're done with it, but that
won't affect whether you can be called when the event is raised).
If no one else catches the error, you should post a concise-but-complete
example of code that demonstrates the problem. Assuming I didn't miss
anything, the fact that it's still not working means that there's
something in the code you didn't post that's causing a problem.
Having a concise-but-complete code example would allow anyone to just
compile the thing and test it themselves. Since there's nothing about
what you're trying to do that requires a form, the code you post should
actually be a console application. Yes, this means you need to
basically write a new code sample, copying the important bits from the
code that already exists.
Of course, that assumes the code you posted is exactly the code you're
using. If it's not strictly a copy-and-paste from your program, that's
obviously going to prevent anyone from saying what's wrong with the code
you're actually using. :)
Pete
Many thanks - I got it to work. It helps if you actually call the event in
the first place. Doh! This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Andy Read |
last post by:
Hello all,
I have the requirement to produce source code that produces an object
hierarchy.
Example:
Root
|
Folder 1
|
by: Christopher W. Douglas |
last post by:
I am writing a VB.NET application in Visual Studio 2003. I have written a
method that handles several events, such as closing a form and changing the
visible status of a form. I have some code...
|
by: boxboy |
last post by:
I am hoping someone from Microsoft could shed some insight into this
question.
Why did microsoft decide to use a verb based naming convtion for events
rather such as Close and Click for rather...
|
by: Maxine G |
last post by:
I have two forms, a menu and a data entry form. The entry form is bound
to a query against linked SQL server tables. In the deactivate event, I
have some code which asks the user if they want to...
|
by: Edward Diener |
last post by:
According to the CLS specification, the accessibility of the methods for
adding, removing, and raising an event must be identical. There appear to be
a few problems with this:
1) According to...
|
by: Charles Law |
last post by:
I may have asked this before, but what is the purpose of both these
functions? Is there a time when one should be called over the other?
Does one supersede the other, or do they both have their...
|
by: Jack Russell |
last post by:
My unstanding of all VB up to and including vb6 is that an event could
not "interrupt" itself.
For instance if you had a timer event containing a msgbox then you would
only get one message.
...
|
by: Pete |
last post by:
Assume I have an n by n matrix of identical objects, each of which can both
invoke and consume event A. If, say, obect invokes the event, the only
other objects that need to consume it are those in...
|
by: Daniela Roman |
last post by:
Hello,
I try to fire an event under a button click event and maybe anybody can give
a clue please.
I have let's say a WEB grid with PageIndexChanged event:
private void...
|
by: jaysonnward |
last post by:
Hello All:
I've recently been recreating some 'dropdown menus' for a website I
manage. I'm writing all my event handlers into my .js file. I've got
the coding to work in Firefox, but the...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
| |