Beginner Question...

  • Thread starter Thread starter Alex
  • Start date Start date
A

Alex

Hi Everyone,

I'm working through the Beginning Visual Basic 2005 book, but I have a
question that though might be obvious, I'm not seeing an explanation.
THe first example in the book is creating a simple form with two
buttons and a text box, but for example on the OK button, here's waht
is in the .vb file for this object:

Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles
End Sub

Can someone explain what all this is? I know btn_OK is the name I
gave the button, and _Click I assume is the action (when you click on
it, run this sub). But what's the rest, like everything in the
parenthesis? What does all this mean?

Alex
 
Alex said:
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles
End Sub

There should be a bit more after the 'Handles' keyword:

\\\
[...] Handles btnOK.Click
///

Anyway, the bits are as follows:

btnOK_Click is just the name of the procedure. You could call it anything
you like, but by convention the procedure will be the name of the control
(btnOK), an underscore and then the event it is handling (Click). In VB6,
the procedure name was the thing that identified this as the click handler
for the button, so it had to be named in this way; in .NET that's no longer
the case but usually control event handlers are named in this fashion.

The bit in the parentheses are parameters that .NET passes to the procedure
to help you work out what's going on.

"sender" is the object that initiated the event. In the case of your button
click event, it'll point to the button itself. In other circumstances there
could be lots of different controls that can cause the event to fire, and in
these cases you can use sender to work out which one it was.

"e" is an object that contains information relevant to the event. Different
events will use different object types for this parameter. The
System.EventArgs doesn't have anything useful within it, but if for example
this were a KeyPress handler, you could use the object provided in e to work
out which key was pressed, which modifier keys were down, and to indicate
back to VB that you have handled the keypress yourself, if you wish.

Finally the "Handles btnOK.Click" is the bit that actually wires this
procedure up to the Click event of the btnOK button. If you take this bit
out, the procedure will no longer react to clicks. Again, you'll notice that
different event handlers specify different event types in this part of the
procedure declaration.

Hope that helps,
 
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles
End Sub
Can someone explain what all this is? I know btn_OK is the name I
gave the button, and _Click I assume is the action (when you click on
it, run this sub). But what's the rest, like everything in the
parenthesis? What does all this mean?


btnOK_Click is the name of the method. It was created by the form designer
when you double clicked the button on the designer surface. This method is
technically known also as an event.

The text inside the parenthesis represent 2 parameters.

By convention the parameters to the event are....
....Sender: The object responsible for calling the method
....e : a structure with properties and methods related to the type of event
being called/raised.

The idea behind Sender is that you can hookup multiple buttons to work against
the same event and can use Sender to differentiate between them.

The e object passed to a button's Click event is just the defacto System.EventArgs.
It copnveys little to no information that is really useful.

Your posted code is however missing some detail.

After the "Handles" keyword is missing the phrase " btnOk.Click"

This is the code which tells your program to call/raise this event when the
button is clicked.

If your program is working, then this code is present and you simply did
not copy all of it into your post.


Try adding a second button to your form called "btnCancel"... then replace
the method you pasted into your message with this...
 
Alex said:
I'm working through the Beginning Visual Basic 2005 book, but I have a
question that though might be obvious, I'm not seeing an explanation.
THe first example in the book is creating a simple form with two
buttons and a text box, but for example on the OK button, here's waht
is in the .vb file for this object:

Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles
End Sub

Can someone explain what all this is? I know btn_OK is the name I
gave the button, and _Click I assume is the action (when you click on
it, run this sub). But what's the rest, like everything in the
parenthesis? What does all this mean?

"Private" - this method is only accessible within the class that defines
it. Nothing outside of this class can use this method directly.

"Sub" - a method that doesn't return a value.

"btnOK_Click" - the method name. The /convention/ for Event Handlers
like this is <ControlName>_<EventName>. It's only a convention; there's
nothing to stop you calling this method "Fred".

"( ... )" - Arguments to the method. Since this is an event handler,
there's a convention for these as well ...

"ByVal sender as Object" - sender is a reference (dare I say "Pointer")
to the object that raised this event, /whatever/ that might be. It's
typed "As Object" because it really could be /any/ object you can
define, and Object is the base class for all other objects. Using this
reference, you can access the control that sent you the event, so that
you can manipulate it, but you have to know what Type it is:

Private Sub Button1_Click( _
ByVal sender as Object _
, byval e as EventArgs _
) Handles Button1.Click

DirectCast(sender, Button).Enabled = False

End Sub

"ByVal e as EventArgs" - e is a reference to an object that tells you
more about this particular event. In this case, there isn't much else
to say - the control got clicked on - but other events have some quite
extensive event arguments.

"Handles <ControlName>.<EventName>" - this may feel a bit redundant in
this case, because your event name and the actual event it's handling
are [almost] identical BUT, in the Brave New, Object-Oriented World.Net,
you can have one event handler .. er .. handling the events from more
than one object, as in ...

Private Sub AnyButton_Click( _
ByVal sender as Object _
, byval e as EventArgs _
) Handles Button1.Click, Button2.Click, Button3.Click

' This routine is called when ANY
' of the three buttons is clicked

End Sub

.... and more than one event handler handling the /same/ event from a
single control, as in ...

Private Sub Button1_Click( _
ByVal sender as Object _
, byval e as EventArgs _
) Handles Button1.Click
' Button1's own "click" handler

End Sub

Private Sub Poacher( _
ByVal sender as Object _
, byval e as EventArgs _
) Handles Button1.Click
' This one ALSO gets called when Button1 is clicked!
' AFAIK, you can't guarantee the order they're called in.

End Sub

You may also see the "AddHandler" statement in people's code
(particularly if you get C# samples). This statement does the same
thing as (and, indeed, replaces) the "Handles" clause, but does it at
/run-time/ and is used when, say, you're adding Controls dynamically but
still need to handle their events.

AddHandler Button4.Click, AddressOf Button4_Click

HTH,
Phill W.
 
I'm not the OP, but thanks Phill W for your very complete response to Alex.
Two questions related to part of your response ...

If an event handler is exclusively for a Button click, could you declare the
first argument as "ByVal sender as Button" instead of "ByVal sender as
Object"? Also, if sender is ByVal, are you really changing anything in the
statement ...

DirectCast(sender, Button).Enabled = False

My understanding is that you would be changing something in a copy of
'sender' and that the caller would not be aware of any change to a ByVal
object.

Thanks, Bob
 
eBob.com said:
I'm not the OP, but thanks Phill W for your very complete response to Alex.
Two questions related to part of your response ...

If an event handler is exclusively for a Button click, could you declare the
first argument as "ByVal sender as Button" instead of "ByVal sender as
Object"?

[Annoyingly] Probably not.
Your method has to "match" the signature of the event delegate method
that you want it "hooked up" to. That sounds clumsy but, here's what I
think the compiler does:

You code:

Sub X_Click( sender as Object, e as EventArgs ) Handles X.Click

The compiler takes this and churns it around into something more like

Sub X_Click( sender as Object, e as EventArgs)

.... and ...

AddHandler X.Click, AddressOf X_Click

.... which, internally, gets churned into ...

AddHandler X.Click, New ClickEventHandler( X_Click )

"ClickEventHandler" is a delegate method that gets called when the event
is raised. Each event can have lots of these delegated methods, which
is how you can have many routines handling a single event.

For this last line to work, though, the signature of "X_Click" has to
"match" the signature of the ClickEventHandler delegate method - just
how tightly the compiler enforces this, I don't know.

Best advice: try it and see! ;-)

Also, if sender is ByVal, are you really changing anything in the
statement ...

DirectCast(sender, Button).Enabled = False

Remember: you're playing with Objects here, not basic, Value Types.
(Damn! I miss not being able to say "Pointer"!)

Whenever you have a variable "containing" an Object, you /don't/
actually have the whole object - you only have a "reference" (a.k.a
"Pointer") to that object; the compiler does all the de-referencing for
you so you don't notice the difference, so when you say

Sub X_Click( Byval sender as Object ...

.... you're passing the /reference/ By Value, not the whole object.
You /can/ change the properties on that object (as in my example) but
what you /can't/ do is assign and return a whole /new/ object, so ...

Sub Button1_Click( Byval sender as Object ...
sender = New Button()

.... /won't/ have any effect on the original button.

My understanding is that you would be changing something in a copy of
'sender' and that the caller would not be aware of any change to a ByVal
object.

Nope. Pass an Object By Value and you can still modify /that instance/
of the object. If you want to "return" a /new/ instance, though, you
have to pass the reference By Reference.

BTW, there's no easy way to "copy" an Object; there internals are so
variable that the framework simply can't do the job automatically; you
have to code a [ICloneable.]Clone method yourself.

HTH,
Phill W.
 
Back
Top