Understanding an event question GDI+ example

J

jm

From a C. Petzold book I have Programming Windows C#. It's a little
old now, but anyway, it has on page 71 (shortened):

form.Paint += new PaintEventHandler(MyPaintHandler);

static void MyPaintHandler(object objSender, PaintEventArgs pea)
{
Graphics grfx = pea.Graphics;
grfx.Clear(Color.Chocolate);
}

When the paint event occurs the MyPaintHandler fires. In there, and
now I am guessing, the .NET framework sends the object that causes the
event (form here) as the first argument in MyPaintHandler (objSender),
then it sends an instantiated Graphics class (pea).

What happens to the objSender? Why does it just "disappear"? This
signature in .NET events has always confused me. What happens to that
object objSender sent to the event handler? No code there, so I don't
get it.

A specific GDI+ question, but it is related because there is always in
the events some kind of xxxxEventArgs in my applications. I know how
to use them, but I don't always understand why I need them. I just
mindlessly follow what other snippets do. Anyway, why do I need the
PaintEventArgs here? Why do I have to take a Graphics object, assign
it to pea, assign that to PaintEventArgs and then turn around and say:

Graphics grfx = pea.Graphics;

so that I can call:

grfx.Clear(Color.Chocolate);

Why couldn't I just have said:

pea.Clear(Color.Chocolate); ?

Thank you for helping me understand why things work, instead of just
what works.
 
P

Peter Duniho

jm said:
[...]
When the paint event occurs the MyPaintHandler fires. In there, and
now I am guessing, the .NET framework sends the object that causes the
event (form here) as the first argument in MyPaintHandler (objSender),
then it sends an instantiated Graphics class (pea).

No. It "sends" (passes as the second argument) a reference to an
instantiated PaintEventArgs class instance, which happens to contain a
reference to an instantiated Graphics class instance.
What happens to the objSender? Why does it just "disappear"?

What do you mean by "disappear"? It doesn't go anywhere. It just doesn't
happen to be used in this case. The "object" argument for the event handler
is often unused...it's provided for convenience in case the code does need
to use it, but it is not required to be used.
This
signature in .NET events has always confused me. What happens to that
object objSender sent to the event handler? No code there, so I don't
get it.

This is the standard general purpose "pattern" for event handlers. The
first argument to the handler method is a reference to the object, and the
second is a reference to the EventArgs (either an EventArgs itself, or some
class derived from EventArgs, as the case here). In some cases, neither
argument is actually needed, but they are always provided so that the events
can follow a standardized structure.
A specific GDI+ question, but it is related because there is always in
the events some kind of xxxxEventArgs in my applications. I know how
to use them, but I don't always understand why I need them. I just
mindlessly follow what other snippets do. Anyway, why do I need the
PaintEventArgs here?

Because that's the derived type used specifically with the Paint event.
Why do I have to take a Graphics object, assign
it to pea,

There is no code assigning a Graphics object to the "pea" argument. Doing
that would make no sense.
assign that to PaintEventArgs and then turn around and say:

Graphics grfx = pea.Graphics;

so that I can call:

grfx.Clear(Color.Chocolate);

Why couldn't I just have said:

pea.Clear(Color.Chocolate); ?

The argument "pea" has type PaintEventArgs. That type does not have a Clear
method, nor is there any reason for it to. Without a Clear method, the line
of code you suggest is illegal.

The PaintEventArgs class exists solely to contain data relevant specific to
the event in question. In this case, that's the Paint event, and so it
contains the generic things found in EventArgs, along with a reference to a
Graphics object, which is needed to actually draw.

You could just have written:

pea.Graphics.Clear(Color.Chocolate);

instead, but it's common practice to go ahead and store the Graphics
reference in a local variable so that the object can be referenced using
more concise code.

Pete
 
J

jm

Peter said:
jm said:
[...]
When the paint event occurs the MyPaintHandler fires. In there, and
now I am guessing, the .NET framework sends the object that causes the
event (form here) as the first argument in MyPaintHandler (objSender),
then it sends an instantiated Graphics class (pea).

No. It "sends" (passes as the second argument) a reference to an
instantiated PaintEventArgs class instance, which happens to contain a
reference to an instantiated Graphics class instance.
What happens to the objSender? Why does it just "disappear"?

What do you mean by "disappear"? It doesn't go anywhere. It just doesn't
happen to be used in this case. The "object" argument for the event handler
is often unused...it's provided for convenience in case the code does need
to use it, but it is not required to be used.
This
signature in .NET events has always confused me. What happens to that
object objSender sent to the event handler? No code there, so I don't
get it.

This is the standard general purpose "pattern" for event handlers. The
first argument to the handler method is a reference to the object, and the
second is a reference to the EventArgs (either an EventArgs itself, or some
class derived from EventArgs, as the case here). In some cases, neither
argument is actually needed, but they are always provided so that the events
can follow a standardized structure.
A specific GDI+ question, but it is related because there is always in
the events some kind of xxxxEventArgs in my applications. I know how
to use them, but I don't always understand why I need them. I just
mindlessly follow what other snippets do. Anyway, why do I need the
PaintEventArgs here?

Because that's the derived type used specifically with the Paint event.
Why do I have to take a Graphics object, assign
it to pea,

There is no code assigning a Graphics object to the "pea" argument. Doing
that would make no sense.
assign that to PaintEventArgs and then turn around and say:

Graphics grfx = pea.Graphics;

so that I can call:

grfx.Clear(Color.Chocolate);

Why couldn't I just have said:

pea.Clear(Color.Chocolate); ?

The argument "pea" has type PaintEventArgs. That type does not have a Clear
method, nor is there any reason for it to. Without a Clear method, the line
of code you suggest is illegal.

The PaintEventArgs class exists solely to contain data relevant specific to
the event in question. In this case, that's the Paint event, and so it
contains the generic things found in EventArgs, along with a reference to a
Graphics object, which is needed to actually draw.

You could just have written:

pea.Graphics.Clear(Color.Chocolate);

instead, but it's common practice to go ahead and store the Graphics
reference in a local variable so that the object can be referenced using
more concise code.

Pete

Thank you.

General OOP question about this, please. The PaintEventArgs class has
a reference to yet another class? I guess I've only seen simple
classes or not really thought about them containing references to other
classes. Does the Graphics class reference here mean anything
concerning inheritance? Graphics doesn't inherit anything from
PaintEventArgs or isn't related somehow that allows the reference in
the PaintEventArgs to the Graphics class or could there have been a
reference to any class (assuming I could use it here)?
 
P

Peter Duniho

jm said:
General OOP question about this, please. The PaintEventArgs class has
a reference to yet another class?

Yes. You can put any sort of data into a class that you want, including a
reference to another class instance. A reference to *any* class instance.
I guess I've only seen simple
classes or not really thought about them containing references to other
classes. Does the Graphics class reference here mean anything
concerning inheritance?

No, it doesn't relate to inheritance at all.
Graphics doesn't inherit anything from
PaintEventArgs or isn't related somehow that allows the reference in
the PaintEventArgs to the Graphics class or could there have been a
reference to any class (assuming I could use it here)?

The reference could have been anything. It just happens in this case that
it makes sense for the PaintEventArgs to contain a reference to an instance
of the Graphics class.

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