473,385 Members | 1,542 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Using a Delegate to Simulate Invoking Events in Base Class

I have a base class and derived classes that relate to a set of documents I
process. e.g. DocBase, DocA, DocB, DocC. The processing of each document is
handled in teh derived classes, as you might imagine, but the base class has
properties and methods that are common to all documents.

The processing of each docuemnt can result in a range of document specific
errors, which I want to raise as events on the document object, but there
are some events that are common to all documents, so I would like to have
those raised in the base class. In fact, I want to raise all events through
a delegate in the base class so that the object owners don't have to do too
much work.

So, I have in mind something like this for the caller:

Main
Sub ProcessDocA
Dim doc As DocBase = New DocA(path)

doc.Process(AddressOf DocA_ProcessError) <--- Problem here
End Sub

Sub ProcessDocB
Dim doc As DocBase = New DocB(path)

doc.Process(AddressOf DocB_ProcessError) <--- Problem here
End Sub

Sub DocA_ProcessError(ByVal sender As Object, ByVal e As
DocAProcessErrorEventArgs)
' Prompt User
End Sub

Sub DocB_ProcessError(ByVal sender As Object, ByVal e As
DocBProcessErrorEventArgs)
' Prompt User
End Sub

My base class looks like this

Public MustInherit Class DocBase

Delegate Sub ProcessErrorEventHandler(ByVal sender As Object, ByVal
e As EventArgs)

Protected ProcessErrorCallBack As ProcessErrorEventHandler

MustOverride Sub Process(ByVal callback As ProcessErrorEventHandler)

Protected Sub OnProcessError(ByVal e As EventArgs)
ProcessErrorCallBack.Invoke(Me, e)
End Sub

End Class

My derived class looks like this

Public Class DocA

Inherits DocBase

Public Overrides Sub Process(ByVal processErrorCallback As
ProcessErrorEventHandler)
MyBase.ProcessErrorCallback = processErrorCallback

DoProcessing()

End Sub

Private Sub Do Processing()

' Trap Error
MyBase.OnProcessError(New DocAProcessErrorEventArgs("Error in
Doc A"))

End Sub

End Class
The problem is where I have arrowed above, becase the compiler doesn't like
an implicit narrowing conversion from DocA_ProcessError() to
ProcessErrorEventHandler.

I know this all looks very complicated, and perhaps unnecessarily so, but
can anyone suggest a better, more generic way to do this.

TIA

Charles
Sep 27 '08 #1
6 1563
Have you tried or do you know about events with the standard OnXXXX
sub raising the XXXX event ? In your description you are talking
multiple times about events but you are using delegates in your code
so I'm not sure if you know about events or if you are trying to avoid
them for some reason (not sure what is this "too much work" you are
talking about)...
--
Patrice
Sep 27 '08 #2
Hi Patrice

Thanks for the reply. I do know about events, but as I understand it events
in a base class can't be raised by a derived class, so that is why I'm using
delegates. They also can' te b used as a contract in an interface, which is
another goal.

The too much work I'm talking about is work the client of my Doc classes has
to do. I thought that if they just passed a reference to a call back to
handle errors then that would be the easiest solution. I also mean that I
want to impose some sort of contract on the user so that I can use the
compiler to pickup errors at design time if the classes are not used
correctly. Also, if I can create an interface in a particular way, it will
ensure that the rest of the code is written correctly.

Charles
"Patrice" <pa************@hotmail.comwrote in message
news:4e**********************************@34g2000h sh.googlegroups.com...
Have you tried or do you know about events with the standard OnXXXX
sub raising the XXXX event ? In your description you are talking
multiple times about events but you are using delegates in your code
so I'm not sure if you know about events or if you are trying to avoid
them for some reason (not sure what is this "too much work" you are
talking about)...
--
Patrice

Sep 27 '08 #3
Try :

MustInherit Class DocBase
Event ProcessingError()
Protected Overridable Sub OnProcessingError()
Debug.WriteLine("Here in DocBase.OnProcessingError")
RaiseEvent ProcessingError()
End Sub
MustOverride Sub Processing()
End Sub
End Class

Class DocA
Inherits DocBase
Sub Processing()
OnProcessingError()
End Sub
Sub Test() Handles Me.ProcessingError
Debug.WriteLine("Here in DocA.Test that handles
ProcessingError")
End Sub
End Class

It will display both messages. Is this what you are looking for ?

If not the problem in your first code is that you seems to use a
specific argument type for each of your child class. It should work if
you replace DocAProcessEventArgs, DocB... by just EventArgs so that it
match what you used in the base class.
--
Patrice

Sep 28 '08 #4
Hi Patrice

I can see what you have done there, and you are right that I am using a
specific argument type for each of my derived classes.

I agree that that is the problem, so perhaps I have to find a way to make
the argument common, even if it is not EventArgs. Currently, each derived
class returns specific information relating to the document it is
processing, so I'm not sure how to make the argument common, but I will try.
It would be nice to find a generic way to do it where the argument types
were different though.

Thanks.

Charles
"Patrice" <pa************@hotmail.comwrote in message
news:b4**********************************@c65g2000 hsa.googlegroups.com...
Try :

MustInherit Class DocBase
Event ProcessingError()
Protected Overridable Sub OnProcessingError()
Debug.WriteLine("Here in DocBase.OnProcessingError")
RaiseEvent ProcessingError()
End Sub
MustOverride Sub Processing()
End Sub
End Class

Class DocA
Inherits DocBase
Sub Processing()
OnProcessingError()
End Sub
Sub Test() Handles Me.ProcessingError
Debug.WriteLine("Here in DocA.Test that handles
ProcessingError")
End Sub
End Class

It will display both messages. Is this what you are looking for ?

If not the problem in your first code is that you seems to use a
specific argument type for each of your child class. It should work if
you replace DocAProcessEventArgs, DocB... by just EventArgs so that it
match what you used in the base class.
--
Patrice

Sep 28 '08 #5
refering to the Foo event in Bill McCarthy's reply, there are several ways of
defining different event data for each derived class. One way is to define a
base class event args
Friend Class FooBaseEventArgs
Inherits System.EventArgs

Friend New( .. )

.. you can include an e.g. typeID so the comsumer can determine
.. the actual eventargs type,
.. Or use typeof or some other logic

.. properties ..
end class

then
Friend Class Derived1_FooEventArgs
Inherits FooBaseEventArgs

...
End Class

and so on...

In the base class,
Protected Sub OnFoo(ev as FooBaseEventArgs)
( you don't need the Overriable if you are only going to invoke the event)

Then in the derived class,
Dim eArgs as New Derived1_FooEventArgs(..)
OnFooEvent(eArgs)

There are other schemes for accomplishing the same thing. It is then up to
the comsumer of the event to sort out the desired data from the event data
--
JB
"Bill McCarthy" wrote:
Hi Charles,

"Charles Law" <bl***@nowhere.comwrote in message
news:uB**************@TK2MSFTNGP03.phx.gbl...
Hi Patrice

Thanks for the reply. I do know about events, but as I understand it
events in a base class can't be raised by a derived class, so that is why
I'm using delegates.

The Usual Pattern there is to have:

Class BaseClass

Event Foo As EventHandler

Protected Overridable Sub OnFoo(ev as eventargs)
RasieEvent Foo(Me,ev)
End sub
End CLass

Class Derived : Inherits BaseClass

Sub Dosomething
OnFoo(eventargs.empty)
End sub
End Class

They also can' te b used as a contract in an interface, which is another
goal.


Yes they can.
Sep 28 '08 #6
Hi JB

My news reader isn't showing Bill's reply, so I have only just seen it in
your reply below.

I started down this route, and then decided that I didn't want the consumer
to have to cast the eventargs parameter received to the specific derived
eventargs type for the event. I wanted them to receive the correctly typed
parameter for the event raised by the derived class.

Charles
"JB" <JB@discussions.microsoft.comwrote in message
news:DD**********************************@microsof t.com...
refering to the Foo event in Bill McCarthy's reply, there are several ways
of
defining different event data for each derived class. One way is to
define a
base class event args
Friend Class FooBaseEventArgs
Inherits System.EventArgs

Friend New( .. )

.. you can include an e.g. typeID so the comsumer can determine
.. the actual eventargs type,
.. Or use typeof or some other logic

.. properties ..
end class

then
Friend Class Derived1_FooEventArgs
Inherits FooBaseEventArgs

...
End Class

and so on...

In the base class,
Protected Sub OnFoo(ev as FooBaseEventArgs)
( you don't need the Overriable if you are only going to invoke the
event)

Then in the derived class,
Dim eArgs as New Derived1_FooEventArgs(..)
OnFooEvent(eArgs)

There are other schemes for accomplishing the same thing. It is then up
to
the comsumer of the event to sort out the desired data from the event data
--
JB
"Bill McCarthy" wrote:
>Hi Charles,

"Charles Law" <bl***@nowhere.comwrote in message
news:uB**************@TK2MSFTNGP03.phx.gbl...
Hi Patrice

Thanks for the reply. I do know about events, but as I understand it
events in a base class can't be raised by a derived class, so that is
why
I'm using delegates.

The Usual Pattern there is to have:

Class BaseClass

Event Foo As EventHandler

Protected Overridable Sub OnFoo(ev as eventargs)
RasieEvent Foo(Me,ev)
End sub
End CLass

Class Derived : Inherits BaseClass

Sub Dosomething
OnFoo(eventargs.empty)
End sub
End Class

They also can' te b used as a contract in an interface, which is
another
goal.


Yes they can.

Sep 28 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Todd Schinell | last post by:
Back in July, Jeffery Tan posted this: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=OWOTdf0VDHA.2296%40cpmsftngxa06.phx.gbl In response as to how to get click events from a...
9
by: Guy | last post by:
I have extended the datetimepicker control to incorporate a ReadOnly property. I have used the new keyword to implement my own version of the value property, so that if readonly == true then it...
11
by: ZorpiedoMan | last post by:
This is either a bad bug, or I'm not understanding somthing. In my mind, this should NOT work: ------------------------------------------ Class ShouldntWork Delegate Sub goHere() Sub...
7
by: tony | last post by:
Hello! What is the differens if I use event handler onSizeChanged compare to using the other event handler MeltPracForm_SizeChanged. I see both as event handler is that right? I catch the event...
0
by: Haxan | last post by:
Hi, I have an unmanaged application that converts a function pointer to a delegate and then pass this as a parameter(delegate) to a managed function which then invokes it. Currently Im able to...
2
by: MuZZy | last post by:
Hi, Consider i have this code: // --------------------------------------------------------------------- public delegate void DoSearchEventHandler(Form f, DoSearchEventArgs e); public class...
6
by: RobKinney1 | last post by:
Hello, This may be an easy question, but I cannot stumle upon the correct way of doing this. I have a function in a base class. I then pass it to a class as a delegate so I don't have to...
2
by: mswlogo | last post by:
I looked high and low for code to do this and finally found some VB code that did it right. This is a C# flavor of it. public event EventHandler<EventArgsMyEventToBeFired; public void...
5
by: raylopez99 | last post by:
I have a form, Form6, that has a bunch of buttons overlaid on it. I want to be able to click on any arbitrary area of the form, and if that area of the form is overlaid by a button, I want to...
6
by: Charles Law | last post by:
I have a base class and derived classes that relate to a set of documents I process. e.g. DocBase, DocA, DocB, DocC. The processing of each document is handled in teh derived classes, as you might...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.