can a method implement an interface and handle an event at the same time?

K

keith.thornhill

hi all,

lets say i have a usercontrol which implements a custom interface. like
so:

-------------------------------------------------

interface IMyInterface
sub buttonClick()
end interface

class MyParentControl
protected MyButton as Button
end class

class MyUserControl
inherits MyParentControl
implements IMyInterface

sub buttonClick() implements IMyInterface.buttonClick
end sub
end class

-------------------------------------------------

here's the catch. i want MyUserControl.buttonClick to also handle
MyButton.Click(), and i want the code that wires up that event to be in
MyParentControl, not MyUserControl.

is it possible? when i try to put "AddHandler MyButton.Click, AddressOf
Me.buttonClick" in MyParentControl, the compiler tells me that
buttonClick is not a member of MyParentControl (obviously)

not sure how i should move forward here. putting the AddHandler call
into MyUserControl is something i'd like to avoid.

thanks!
 
M

Mattias Sjögren

is it possible?

You can do it like this

MustInherit class MyParentControl
protected WithEvents MyButton as Button

Protected MustOverride Sub buttonClick() Handles MyButton.Click
end class

class MyUserControl
inherits MyParentControl
implements IMyInterface

Protected Overrides sub buttonClick() implements
IMyInterface.buttonClick
end sub
end class


Mattias
 
K

keith.thornhill

true, but VS 2005 still cannot open abstract classes in design view,
which is one of the primary features of the code i am trying to write.
(the old code is abstract and i'm purposefully changing from that.)

i'm just trying to find out if there is a clean way to mimic the
abstract method definitions while avoiding abstract classes. i do
realize that i can't force any classes which inherit from
MyParentControl to also implement IMyInterface, but since interfaces
are the only other way i know of which enforce certain methods to be
defined that is the route i am trying to take.

but thank you for the suggestion

-keith
 
P

Phill W.

interface IMyInterface
sub buttonClick()
end interface

class MyParentControl
protected MyButton as Button
end class

class MyUserControl
inherits MyParentControl
implements IMyInterface

sub buttonClick() implements IMyInterface.buttonClick
end sub
end class

-------------------------------------------------

here's the catch. i want MyUserControl.buttonClick to also handle
MyButton.Click(), and i want the code that wires up that event to be in
MyParentControl, not MyUserControl.

is it possible?

The biggest problem here is that event handlets have a distinctive
signature - "name( Object, EventArgs )" - that your Interface method
doesn't have. You're going to have to have a /separate/ routine that
does the actual work and call it from (a) the button's "click" handler
and (b) the method that implements the Interface.

Class MyParentControl

Protected WithEvents MyButton as Button

Sub New()
MyButton = New Button
With MyButton
...
End With
End Sub

Protected Sub buttonClick()
' code for dealing with "Click" goes here
End Sub

Private Sub MyButton_Click(sender As Object, e As EventArgs) _
Handles MyButton.Click

Me.buttonClick()

End Sub

End Class


Class MyUserControl
Inherits MyParentControl
Implements IMyInterface

Sub New()
MyBase.New()

End Sub

Private Sub Something() _
Implements IMyInterface.buttonClick

MyBase.buttonClick()

End Sub

End Class

HTH,
Phill W.
 
K

keith.thornhill

i'm sorry, i suppose i should have been more exact; my actual interface
method is defined as

Interface IBaseContractControl
Sub ButtonClick(ByVal sender As System.Object, ByVal e As
System.EventArgs)
End Interface

(i used an empty paramter list to simplify the example, my apologies)

this (in theory) allows me to use a single function located in
MyUserControl which can satisfy the interface and be directly wired up
to the event. i'm just not sure how to wire it up at run time from
MyParentControl. (instead of, for example, calling "AddHandler
MyButton.Click, AddressOf ButtonClick" in MyUserControl's constructor)

-keith
 
C

Chris Dunaway

i'm sorry, i suppose i should have been more exact; my actual interface
method is defined as

Interface IBaseContractControl
Sub ButtonClick(ByVal sender As System.Object, ByVal e As
System.EventArgs)
End Interface

(i used an empty paramter list to simplify the example, my apologies)

this (in theory) allows me to use a single function located in
MyUserControl which can satisfy the interface and be directly wired up
to the event. i'm just not sure how to wire it up at run time from
MyParentControl. (instead of, for example, calling "AddHandler
MyButton.Click, AddressOf ButtonClick" in MyUserControl's constructor)

You will need to add an event to your user control that is exposed to
your controls parent. Then inside your button click, you need to raise
that event.
 
K

keith.thornhill

thank you everyone for the help.

here is how i solved it:

this method was added to MyParentControl

Private Function AddInterfaceHandler(ByVal EventName As String, ByVal
InterfaceMethod As String) As Boolean

Dim objType As Type
Dim deleg As System.Delegate
Dim evInfo As System.Reflection.EventInfo

Try
objType = GetType(BaseContractControl(Of Thelper, Tsps))
evInfo = objType.GetEvent(EventName)
deleg =
System.Delegate.CreateDelegate(evInfo.EventHandlerType, Me,
InterfaceMethod)
evInfo.AddEventHandler(Me, deleg)

Return True
Catch ex As Exception
' derived must have not implemented the interface

Return False
End Try

End Function

this function could easily be made to wire directly to the objects
firing the events (i.e. the button) if you add a "Target as Object"
parameter and change the final "AddEventHandler" call to pass that
object rather than Me.

but since i've adjusted MyParentControl to handle the button click
event directly and then fire off its own event, i could hardcode that
call.

-keith
 

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