Sam Marrocco
Sam Marrocco

Reputation: 113

Overriding inherited events & arguments in vb.net

I've created a Custom Control that inherits a PictureBox control. I'd like to add some additional data to the MouseMove event that is returned when the new CustomControl is added to a TestApp. Currently the raised event would appear in the TestApp as

Private Sub MyCustomControl_MouseMove(sender as object, 
      e as MouseEventArgs) handles MyCustomControl.MouseMove

My first thought was to add additional arguments such as

Private Sub MyCustomControl_MouseMove(sender as object, 
      e as MouseEventArgs, MyExtraArgument as double) handles MyCustomControl.MouseMove

or as an alternative, add my extra argument to the MouseEventArgs class so it would appear as

e.MyExtraArgument

Is either of these methods possible? I'm under the impression that these events/objects may not be overridden without being able to modify the original source code of the parent control. Are there any examples of doing either of these techniques? Ideally I'd like to keep all the code within my newly created control library so that the TestApp doesn't require anything other than dropping the newly created child control into it.

More info.... I'll elaborate a bit more....the reason for the additional args is that I have implemented an auto-scaling, autotranslating cartesian coordinate system to the inherited picturebox without using matrix and GDI-inherent scaling methods. To make the new picturebox control easily accessible I wished to override the existing events that return X/Y as integers, permitting them to return doubles or decimals. It seemd better in this case for MouseEventArgs to be extended.

Upvotes: 1

Views: 2450

Answers (1)

It is hard to imagine what is lacking in MouseEventArgs that you need to extend it. There are several problems though:

  • You cannot just add a third argument because the MouseMove event signature will not allow it.
  • You can subclass and extend MouseEventArgs adding your third param, but you cannot use it in the standard MouseMove event, because the event signature wont allow it.

You could consume the standard MouseMove event, and raise a new custom one using an extended event args class. But this will only prevent the old event from firing, not displaying as an available event. This will confuse everyone and make it seem like the event is broke.

You can respond to the standard MouseMove and raise and additional event allowing both to exist:

Inherited Control

Public Event MouseMoved(sender As Object, e As MouseMovedEventArgs)

Public Class MouseMovedEventArgs : Inherits MouseEventArgs

    Public Property NewProperty As Double

    Public Sub New(btns As MouseButtons, clicks As Integer,
                   x As Integer, y As Integer, delta As Integer,
                   newThing As Double)

        MyBase.New(btns, clicks, x, y, delta)
        NewProperty = newThing

    End Sub
End Class

Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
    MyBase.OnMouseMove(e)

    RaiseEvent MouseMoved(Me, New MouseMovedEventArgs(e.Button, 
                                e.Clicks, e.X, e.Y, e.Delta, 3.14R))
End Sub

Having two very similar events will not confuses users any less; it will be easy to subscribe to the wrong one by accident.

In general, I suspect this is an XY problem much more easily solved by adding an event directly related to whatever information MyExtraArgument represents rather than trying to squeeze more information into existing events.


I wished to override the existing events that return X/Y as integers, permitting them to return doubles or decimals.

I dont see how that is specifically and solely mouse move related. If you do consume MouseMove, the user can no longer get the coords relative to the control, only scaled to the image.

Then, what happens for MouseClick? Do you want to replace/override/mirror all the mouse events? What happens when the user needs that info outside a Mouse event?

A better approach might be to provide some to/from converters.

Public Property Scale As Single      ' eg 0.15 to 1.95

Public Function ConvertToScale(pt As Point) As PointF
    ' pt == mouse loc from Click event or whatever
    '        relative to the control
    ' Returns the point relative to the image

Public Function ConvertFromScale(ptF As PointF) As Point
    ' does the reverse

Now, at any point, the code using the control can convert or get and (X, Y) location whenever they need it. BTW Single should be enough and prevent you from reinventing a wheel.

Upvotes: 1

Related Questions