using events (conceptual)

R

rno

Hi,

I am very much struggling with C#/OOP concepts. Coming from a
(limited) VB6 background, I am trying to make the transition to C#.

Something that still eludes me, despite reading dozens of tutorials on
the subject, is delegates/events. I think/hope I understand the basic
concept of it, but to be honest, in practice it is still mostly
trial-and-error.

Currently, I am rewriting a simple app that I once did in VB6, to C#.
From scratch. I figured it would be a good exercise and at least I
know what I want it to do.

It is a form app (just 1 form), that reads data from a 3-rd party app,
and outputs them to several file formats (HTML and XML for now, more
to come?). When a user presses a button, class A is created. In it, I
determine what options a user selected on the form. Those are passed
to a separate static class OutputOptions, so that I do not have to
pass all kinds of settings on fron class to class. Several overloads
of Class A do the same, but do not take the form as parameter. The
idea is that, when I grow up, I might be able to make the 'business
end' of the application into some dll (or whatever) of it's own, for
use in another app - like the one being examined, in which it could be
used to make it 'self-describing'.

Question: does that make sense? (Do I still make sense to you at this
point?)

Class A evaluates the chosen output format, and based on that, it
creates class C, or class D, or... Class C and D both inherit base
class B, that holds stuff common to either class. A major part of that
common stuff is a class ReadTheData, that does all the actual fetching
of data.

So, in essence, class C and D have a shared 'read-the-data' part, and
a custom 'write-the-data' part. I think that makes sense, right?

Now for the interesting bit:
From the 'read-the-data' class ReadTheData, I want to report progress
back to the form. From the 'write-the-data' classes C and D, I also
want to report progress back to the form. However, I would like to
insulate the UI (form) part from the underlying code. So I tried to
use events. I managed to botch up a way to raise the (same) event in
both the base class of the 'write' classes C and D, and in the 'read'
class B, and I created a separate class 'Listener'. Listener contains
the method that I pass to the event handler/delegate thingie (still
don't quite grasp that) for the 'progress' events, and updates the
form - if it exists.

Question: does that make sense?

If you can still follow me, I applaud you. I realise this isn't a
'to-the-point' question, but rather an inquiry whether I am at all on
the right track, not in code, but in concept.

If anyone would like to comment, I'd appreciate that.

tia
arno
 
J

Joe Cool

Hi,

I am very much struggling with C#/OOP concepts. Coming from a
(limited) VB6 background, I am trying to make the transition to C#.

Something that still eludes me, despite reading dozens of tutorials on
the subject, is delegates/events. I think/hope I understand the basic
concept of it, but to be honest, in practice it is still mostly
trial-and-error.

Currently, I am rewriting a simple app that I once did in VB6, to C#.
From scratch. I figured it would be a good exercise and at least I
know what I want it to do.

It is a form app (just 1 form), that reads data from a 3-rd party app,
and outputs them to several file formats (HTML and XML for now, more
to come?). When a user presses a button, class A is created. In it, I
determine what options a user selected on the form. Those are passed
to a separate static class OutputOptions, so that I do not have to
pass all kinds of settings on fron class to class. Several overloads
of Class A do the same, but do not take the form as parameter. The
idea is that, when I grow up, I might be able to make the 'business
end' of the application into some dll (or whatever) of it's own, for
use in another app - like the one being examined, in which it could be
used to make it 'self-describing'.

Question: does that make sense? (Do I still make sense to you at this
point?)

Class A evaluates the chosen output format, and based on that, it
creates class C, or class D, or... Class C and D both inherit base
class B, that holds stuff common to either class. A major part of that
common stuff is a class ReadTheData, that does all the actual fetching
of data.

So, in essence, class C and D have a shared 'read-the-data' part, and
a custom 'write-the-data' part. I think that makes sense, right?

Now for the interesting bit:
From the 'read-the-data' class ReadTheData, I want to report progress
back to the form. From the 'write-the-data' classes C and D, I also
want to report progress back to the form. However, I would like to
insulate the UI (form) part from the underlying code. So I tried to
use events. I managed to botch up a way to raise the (same) event in
both the base class of the 'write' classes C and D, and in the 'read'
class B, and I created a separate class 'Listener'. Listener contains
the method that I pass to the event handler/delegate thingie (still
don't quite grasp that) for the 'progress' events, and updates the
form - if it exists.

Question: does that make sense?

If you can still follow me, I applaud you. I realise this isn't a
'to-the-point' question, but rather an inquiry whether I am at all on
the right track, not in code, but in concept.

If anyone would like to comment, I'd appreciate that.

tia
arno

Actually I had a hard time following your comments. But this link may
provide some help:

http://groups.google.com/group/micr...st&q=event+handling+joe+cool#e0fb60ac088d21d0
 
R

rno

Tx Joe,

Will study that discussion. Basically, I suppose my question boils
down to two things:

-how to (best) raise the same event from unrelated classes?
-how to (best) 'capture' those events and pass them on to another (but
same - that shouldnt even matter should it?) object.

However, that may be oversimplifying things? Hence the elaborate
description of what I am trying to put together.

(BrainOverLoadException)

arno
 
P

Peter Duniho

rno said:
[...]
It is a form app (just 1 form), that reads data from a 3-rd party app,
and outputs them to several file formats (HTML and XML for now, more
to come?). When a user presses a button, class A is created. In it, I
determine what options a user selected on the form. Those are passed
to a separate static class OutputOptions, so that I do not have to
pass all kinds of settings on fron class to class. Several overloads
of Class A do the same, but do not take the form as parameter. The
idea is that, when I grow up, I might be able to make the 'business
end' of the application into some dll (or whatever) of it's own, for
use in another app - like the one being examined, in which it could be
used to make it 'self-describing'.

Question: does that make sense? (Do I still make sense to you at this
point?)

Why does class A need the reference to the Form? Unless class A is
specifically about GUI, it should not need to know anything about your
Form sub-class.

Also, I question the need for a static settings class. Instead, you
should have an object that does all the work related to the settings and
in which you can store a reference to the settings. Global settings
will only restrict you in the future, preventing you from ever having
parallel operations using the same classes that use the settings.
Class A evaluates the chosen output format, and based on that, it
creates class C, or class D, or... Class C and D both inherit base
class B, that holds stuff common to either class. A major part of that
common stuff is a class ReadTheData, that does all the actual fetching
of data.

So, in essence, class C and D have a shared 'read-the-data' part, and
a custom 'write-the-data' part. I think that makes sense, right?

It seems okay. However, you may want to consider separating the reader
and writer portions, following the examples found elsewhere, including
..NET. Then if you ever find yourself needing to source the data from
something different, you can simply write a different reader class to
use to feed the code using the writer class.

In that paradigm, you'd likely have some central "controller" type class
that knows about both the reader and writer and handles transferring the
data between them.
Now for the interesting bit:
From the 'read-the-data' class ReadTheData, I want to report progress
back to the form. From the 'write-the-data' classes C and D, I also
want to report progress back to the form. However, I would like to
insulate the UI (form) part from the underlying code. So I tried to
use events. I managed to botch up a way to raise the (same) event in
both the base class of the 'write' classes C and D, and in the 'read'
class B, and I created a separate class 'Listener'. Listener contains
the method that I pass to the event handler/delegate thingie (still
don't quite grasp that) for the 'progress' events, and updates the
form - if it exists.

Question: does that make sense?

It's not at all clear why your Form sub-class code doesn't just
subscribe directly to the events in question. Why are you writing an
intermediate "Listener" class to do that work?

It certainly can work doing it that way, but it's not clear why that
approach is necessary in your example.

Pete
 
P

Peter Duniho

rno said:
Tx Joe,

Will study that discussion. Basically, I suppose my question boils
down to two things:

-how to (best) raise the same event from unrelated classes?

Unrelated classes can't have "the same event". Can you elaborate on
what that means?
-how to (best) 'capture' those events and pass them on to another (but
same - that shouldnt even matter should it?) object.

One possible approach is to "proxy" an event. For example:

class A
{
B b = new B();

void Handler(object sender, EventArgs e)
{
}

void Method()
{
b.Happened += Handler;
}
}

class B
{
C c = new C();

public event EventHandler Happened;

void Handler(object sender, EventArgs e)
{
RaiseHappened(this, EventArgs.Empty);
}

void RaiseHappened(object sender, EventArgs e)
{
EventHandler handler = Happened;

if (handler != null)
{
handler(sender, e);
}
}

void Method()
{
c.Happened += Handler;
}
}

class C
{
public event EventHandler Happened;

void RaiseHappened(object sender, EventArgs e)
{
EventHandler handler = Happened;

if (handler != null)
{
handler(sender, e);
}
}

void Method()
{
RaiseHappened(this, EventArgs.Empty);
}
}

Whether this applies to your own situation, I don't really know. You're
not specific enough about the details to really understand the design fully.

Pete
 
R

rno

hmm..yes, I can see most of points. I think, anyway. Food for thought.
Tx for the input

arno

rno said:
[...]
It is a form app (just 1 form), that reads data from a 3-rd party app,
and outputs them to several file formats (HTML and XML for now, more
to come?). When a user presses a button, class A is created. In it, I
determine what options a user selected on the form. Those are passed
to a separate static class OutputOptions, so that I do not have to
pass all kinds of settings on fron class to class. Several overloads
of Class A do the same, but do not take the form as parameter. The
idea is that, when I grow up, I might be able to make the 'business
end' of the application into some dll (or whatever) of it's own, for
use in another app - like the one being examined, in which it could be
used to make it 'self-describing'.

Question: does that make sense? (Do I still make sense to you at this
point?)

Why does class A need the reference to the Form? Unless class A is
specifically about GUI, it should not need to know anything about your
Form sub-class.

Also, I question the need for a static settings class. Instead, you
should have an object that does all the work related to the settings and
in which you can store a reference to the settings. Global settings
will only restrict you in the future, preventing you from ever having
parallel operations using the same classes that use the settings.
Class A evaluates the chosen output format, and based on that, it
creates class C, or class D, or... Class C and D both inherit base
class B, that holds stuff common to either class. A major part of that
common stuff is a class ReadTheData, that does all the actual fetching
of data.

So, in essence, class C and D have a shared 'read-the-data' part, and
a custom 'write-the-data' part. I think that makes sense, right?

It seems okay. However, you may want to consider separating the reader
and writer portions, following the examples found elsewhere, including
.NET. Then if you ever find yourself needing to source the data from
something different, you can simply write a different reader class to
use to feed the code using the writer class.

In that paradigm, you'd likely have some central "controller" type class
that knows about both the reader and writer and handles transferring the
data between them.
Now for the interesting bit:
From the 'read-the-data' class ReadTheData, I want to report progress
back to the form. From the 'write-the-data' classes C and D, I also
want to report progress back to the form. However, I would like to
insulate the UI (form) part from the underlying code. So I tried to
use events. I managed to botch up a way to raise the (same) event in
both the base class of the 'write' classes C and D, and in the 'read'
class B, and I created a separate class 'Listener'. Listener contains
the method that I pass to the event handler/delegate thingie (still
don't quite grasp that) for the 'progress' events, and updates the
form - if it exists.

Question: does that make sense?

It's not at all clear why your Form sub-class code doesn't just
subscribe directly to the events in question. Why are you writing an
intermediate "Listener" class to do that work?

It certainly can work doing it that way, but it's not clear why that
approach is necessary in your example.

Pete
 
R

rno

Peter,
It's not at all clear why your Form sub-class code doesn't just
subscribe directly to the events in question. Why are you writing an
intermediate "Listener" class to do that work?

Because, or so I thought, from the form, the event in the class I want
to subscribe to isn't available until I create an instance of that
class. But I don't need the class yet at that point, and if I do so,
and create a second instance to the class elsewhere in my code, the
form will not listen to that one (is that true?). I suppose I could
create a mechanism to pass the instance along, but that seems awkward
at best.

I made the event static, whichs allowed me to subscribe from the form,
but is that a good idea?

As you can probably tell, i am still very much in the process of
struggling to get my mindset right.

arno
 
P

Peter Duniho

rno said:
Because, or so I thought, from the form, the event in the class I want
to subscribe to isn't available until I create an instance of that
class. But I don't need the class yet at that point, and if I do so,
and create a second instance to the class elsewhere in my code, the
form will not listen to that one (is that true?).

Your understanding of the event mechanism is correct. However, that
doesn't really explain the point of the "Listener" class.

Unfortunately, without a concise-but-complete code example showing your
suggested implementation, it's not possible to comment on whether it's
really appropriate or best. But in general, it seems to me that if you
have code somewhere that can subscribe your "Listener" class to the
appropriate instance's event at the right time, you can also subscribe
your Form sub-class to that same event at the right time.

Alternatively, the proxy approach I suggested earlier might be more
appropriate. That is, if the ultimate event you want to subscribe to is
deeper in the object relationship chain than the Form sub-class has
direct access to, then typically you'd provide some event the Form
sub-class _does_ have access to and let it subscribe to that, and then
allow the event itself propagate back from the original to the one the
Form sub-class has subscribed to, via proxying of the event.
[...]
I made the event static, whichs allowed me to subscribe from the form,
but is that a good idea?

Only if you know for sure that you will never ever have the need to
subscribe to the event for more than one instance of your object. In
general, it's a bad idea unless it makes sense to make the whole class
static. Static members that are used to interact with instances doesn't
usually make sense.

Pete
 
R

rno

Pete,

I am struggling with the idea of 'proxying' an event. To me, it seems
to be a mechanism to connect some event to a class that passes on that
event to some other class. I.o.w., passing on information from class
to class (..to class..etc). Perhaps I misunderstand the concept, but
it 'feels' like creating dependencies?

My idea for creating a 'Listener' class, at least in concept, was to
provide some mechanism to report information, contained in some event,
back to (one and only, ever) form, *if it exists*. So in the classes
that raise the event, I create an instance of that listener class and
have it subscribe to the events raised. No matter how deeply buried
that event-raising class is - as long as it implements the listener
class that forwards the event, the form will be updated. That may be a
bad thing, design-wise, but it is the design part that is challenging
me most, I find.

I do not have a concise code example, which may be because I am not
sure how to design my app (yet). But I what I have so far:

form -> class A -> class WriterB | class WriterC | or.. (all
inheriting class Reader) Class A 'controls' the reading and writing -
this might -as you suggested- require rethinking and decoupling of
reader/writer. All mentioned classes, except A, 'do work' and have
progress to report.

I do not want to eliminate class A, for if I ever want to decouple the
UI from the the 'do work' part, class A would be the entry point -uhm-
thingie.

Does this clarify anything? So, what I would like, ideally , is to
have classes writerB, writerC an Reader all report back progress to
the Form. Or whatever assembly that calls the 'business end'.

Building on your idea, what I *think* you suggested is that I prxy
events thru class A to the form, right?

arno

rno said:
Because, or so I thought, from the form, the event in the class I want
to subscribe to isn't available until I create an instance of that
class. But I don't need the class yet at that point, and if I do so,
and create a second instance to the class elsewhere in my code, the
form will not listen to that one (is that true?).

Your understanding of the event mechanism is correct. However, that
doesn't really explain the point of the "Listener" class.

Unfortunately, without a concise-but-complete code example showing your
suggested implementation, it's not possible to comment on whether it's
really appropriate or best. But in general, it seems to me that if you
have code somewhere that can subscribe your "Listener" class to the
appropriate instance's event at the right time, you can also subscribe
your Form sub-class to that same event at the right time.

Alternatively, the proxy approach I suggested earlier might be more
appropriate. That is, if the ultimate event you want to subscribe to is
deeper in the object relationship chain than the Form sub-class has
direct access to, then typically you'd provide some event the Form
sub-class _does_ have access to and let it subscribe to that, and then
allow the event itself propagate back from the original to the one the
Form sub-class has subscribed to, via proxying of the event.
[...]
I made the event static, whichs allowed me to subscribe from the form,
but is that a good idea?

Only if you know for sure that you will never ever have the need to
subscribe to the event for more than one instance of your object. In
general, it's a bad idea unless it makes sense to make the whole class
static. Static members that are used to interact with instances doesn't
usually make sense.

Pete
 
R

rno

Pete,
Also, I question the need for a static settings class. Instead, you
should have an object that does all the work related to the settings and
in which you can store a reference to the settings. Global settings
will only restrict you in the future, preventing you from ever having
parallel operations using the same classes that use the settings.

I can see your point, but I don't think it applies to my situation.

My app will only be allowed a single instance or whatever it is
called. (can't be run more than once).

Even if everything but the UI were to be built into a seperate thingie
like a DLL (how do you call that? Assembly?), that would be
instantiated from other code more than once, that 'static' set of
options would still apply only to that particular instance, am I
right? If that is the case, I should be OK I think.

arno
 
P

Peter Duniho

rno said:
Pete,

I am struggling with the idea of 'proxying' an event. To me, it seems
to be a mechanism to connect some event to a class that passes on that
event to some other class. I.o.w., passing on information from class
to class (..to class..etc). Perhaps I misunderstand the concept, but
it 'feels' like creating dependencies?

You already have dependencies. The point is to manage those
dependencies in a maintainable way.

And yes, you seem to understand the idea of proxying correctly.
[...]
I do not have a concise code example, which may be because I am not
sure how to design my app (yet).

It can be very helpful to write small test projects in which nothing
else is present except possible design approaches that you are trying to
compare. There's nothing better for helping evaluate different options
than to simply implement them and see which seems to work best.
But I what I have so far:

form -> class A -> class WriterB | class WriterC | or.. (all
inheriting class Reader) Class A 'controls' the reading and writing -
this might -as you suggested- require rethinking and decoupling of
reader/writer. All mentioned classes, except A, 'do work' and have
progress to report.

I do not want to eliminate class A, for if I ever want to decouple the
UI from the the 'do work' part, class A would be the entry point -uhm-
thingie.

Does this clarify anything? So, what I would like, ideally , is to
have classes writerB, writerC an Reader all report back progress to
the Form. Or whatever assembly that calls the 'business end'.

Building on your idea, what I *think* you suggested is that I prxy
events thru class A to the form, right?

If class A is the root class that the Form sub-class knows about, and is
how the Form sub-class accesses the functionality implemented by your
"WriterB" and "WriterC" classes, then yes…that sounds like a good approach.

Of course, until you've put something into code, I can't say for sure.
For that matter, even with a code example there's always the possibility
that there's some crucial piece of information left out. But for sure,
without a code example, speaking only in generalities, only general
answers can be offered.

Pete
 

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