MouseHover event question

UberDan

Member
Joined
Nov 27, 2005
Messages
18
Programming Experience
Beginner
Hi guys. Newbie question for ya:

I'm trying to make a simple mousehover effect for a button called btnAdd which changes the background and foreground colors of the button when you move the mouse over it and then reverts back to normal when you leave it. Here's what I've got so far:

VB.NET:
    Private Sub btnAdd_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.MouseHover
        Me.btnAdd.BackColor = System.Drawing.Color.Firebrick
        Me.btnAdd.ForeColor = System.Drawing.Color.White
    End Sub

    Private Sub btnAdd_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.MouseLeave
        Me.btnAdd.BackColor = System.Drawing.Color.RosyBrown
        Me.btnAdd.ForeColor = System.Drawing.Color.Black
    End Sub
It just seems to me like there should be a simpler way. I have to do this for a number of buttons and it makes my code look cluttered. Also, the example .exe that my professor included with the lab assignment shows the effect happening instantly, whereas mine seems to take a small time loading.

I'm using Visual Studio .NET 2003
 
You can have genereric mouse event handler(s) for button and subscribe each button event to the handler with AddHandler/RemoveHandler.

Another option is to create your own usercontrol inherited from button and set specific behaviour there. All buttons you add to an application of this usercontrol type will then behave like this without any more coding needed.
 
JohnH said:
You can have genereric mouse event handler(s) for button and subscribe each button event to the handler with AddHandler/RemoveHandler.

Another option is to create your own usercontrol inherited from button and set specific behaviour there. All buttons you add to an application of this usercontrol type will then behave like this without any more coding needed.

Sorry, but I'm very new to all of this. Could you possibly provide examples?
 
To make the colors change quicker, or right when the mouse enters the control, use the MouseEnter event.
In VB.NET you can have one method handle the event for several control's as long as the signature is the same. There are two ways to accomplish that:
1) as JohnH stated you can use addHandler to wire the events (Microsoft's 'standards' say you should use addhandler sparingly and use the Handles clause were possible)
VB.NET:
'this will wire the events for all button in the form: 
Private Sub _MouseEnter(ByVal sender As Object, _
  ByVal e As System.EventArgs)
    Dim btn as button = CType(Sender, Button)
    btn.BackColor = System.Drawing.Color.Firebrick
    btn.ForeColor = System.Drawing.Color.White
End Sub

Private Sub _MouseLeave(ByVal sender As Object, _
  ByVal e As System.EventArgs)
    Dim btn as button = CType(sender, Button)
    btn.BackColor = System.Drawing.Color.RosyBrown
    btn.ForeColor = System.Drawing.Color.Black
End Sub

Private Sub Form_Load(ByVal sender As Object, _
  ByVal e As System.EventArgs) Handles MyBase.Load
    Dim ctrl As Control
    For Each ctrl In Me.Controls
        If TypeOf ctrl Is Button Then
            AddHandler ctrl.MouseEnter, AddressOf _MouseEnter
            AddHandler ctrl.MouseLeave, AddressOf _MouseLeave
        End If
    Next
End Sub
2) using multiple Handles clauses:
VB.NET:
Private Sub _MouseEnter(ByVal sender As Object, _
  ByVal e As System.EventArgs) _
  Handles btnAdd.MouseEnter, _
  btn2.MouseEnter, _
  btn3.MouseEnter
    Dim btn as button = CType(Sender, Button)
    btn.BackColor = System.Drawing.Color.Firebrick
    btn.ForeColor = System.Drawing.Color.White
End Sub

Private Sub _MouseLeave(ByVal sender As Object, _
  ByVal e As System.EventArgs) _
  Handles btnAdd.MouseLeave, _
  btn2.MouseLeave, _
  btn3.MouseLeave
    Dim btn as button = CType(sender, Button)
    btn.BackColor = System.Drawing.Color.RosyBrown
    btn.ForeColor = System.Drawing.Color.Black
End Sub
To create a usercontrol, add a class then add the Inherits statement (Inherits Button). Then add the code.
 
Thanks a lot man! The multiple handles method was what I was trying to do just now before I read this, but I didn't know about the CType function. This helps tremendously.
 
More info please

when i used your first code i got following errors(marked as red)

AddHandler ctrl.MouseEnter, AddressOf _MouseEnter
AddHandler ctrl.MouseLeave, AddressOf _MouseLeave

could you plz tell me how exactly to use this, do i need to add any code in html side
thank you
 
Example 1 ctrl varable was correctly declared of type Control when iterating the Me.Controls collection, and Button controls were identified by type with TypeOf test, but MouseEnter and MouseLeave are not events of any type control. Since you have tested and found that ctrl in this particular instance is a button, you can cast it to its specific type, which is Button. The button control does indeed bare those events.

dim btn as button = directcast(ctrl, button)
solves that if you put it where it belongs..

A note to Paszt, in example 2 you CType the ctrl to Button. CType translates given object to requested type if the object is compatible to that type, so there must be some conversion being done behind the scenes to achieve this. You can use DirectCast to throw the given object directly into requested type when you know the object is of exactly that type. There is no conversion done with DirectCast behind the scenes, so it will be faster.
 
The last time I checked (and that was just a few seconds ago) MouseEnter and MouseLeave Events are events included in the System.Windows.Forms.Control class. I don't have Vb.NET 2005 yet, but I assume that hasn't changed.

As far as using DirectCast instead of CType in this case, I guess I was reading the article by Microsoft incorrectly. This is there recommendation: "For most conversions, use the intrinsic language conversion keywords (including CType) for brevity and clarity and to allow compiler optimizations when converting between types. Use DirectCast for converting Object to String and for extracting value types boxed in Object variables when the embedded type is known (that is, coercion is not necessary)." Read the entire article here: Visual Basic .NET Internals (look fore a section called 'Conversion Functions, CType, DirectCast, and System.Convert')

The whole 'boxed value types' thing throws me off as I don't understand what boxed means. I guess DirectCast is the correct method here?
 
Those event ramblings of mine was a definitly a bummer hahha :)

As for CType and DirectCast, I don't agree with you, and support my statement further by the quote you give. Control is a general type too, though much more specific than the Object type. Ctype is for coerce conversions (I think of it as translations), and like I said DirectCast for those 'conversion' you know the exact type of the object (read control) to cast.
I found an even better quote in the library for DirectCast keyword:
The difference between the two keywords is that CType succeeds as long as there is a valid conversion defined between the expression and the type, whereas DirectCast requires the run-time type of an object variable to be the same as the specified type. If the specified type and the run-time type of the expression are the same, however, the run-time performance of DirectCast is better than that of CType.
 
Ok, I misinterpret all the time, I think we agree about this after all.
When they say "boxed" in your quote, they are speaking of general type objects that can hold more specific type objects. In this case we iterate various specific type controls with a Control object variable, the Control object variable is a "box" so to speak which can contain any type object derived from Control.
 
Great, thanks for the information JohnH.

Prav_roy: I'm not sure why you would get the error messages. What is the error message that you are getting?
 
Back
Top