By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,201 Members | 914 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,201 IT Pros & Developers. It's quick & easy.

return values from events, eventArgs

P: n/a
I have a 3rd party object that fires an itemchanged event when someone edits
some data on a form. This event has a custom eventArgs that has a field
called ActionCode. In the code of the event, if you set this ActionCode to
various values the control will respond in various ways (reject, reject
change field, accept, etc). I am trying to understand exactly how that
works as I am trying to extend the control and add more processing s events.
In my previous exposure to languages, the events simply had return codes and
I could intercept them in a descendent or ancestor and proccess them.
Obviously it was hiding the whole idea of delegates and such.

I could implement all my code as methods but I would like to be able to put
the code on a form, and still be able to extend or override the framework
code.. I've got a few problems understanding the exact behaviour of the
EventArgs (how to return values) and also how to 'post' and event to fire
when there is no more processing to do. Also how does the eventArgs really
work when there are multiple subscribers? If the first one in the delegate
thread fires should the second one be getting any updates?

This is what I would like to do for letting the user add/insert a new row.
There is a method on the control called InsertRow (int beforeRow){}, 0 = add
to end.

I'm going to define the AddRowEventArgs as (int beforeRow, int actionCode,
int NewRow).

1) User hits button or right mouse to 'Add a new Row'. This calls the
InsertRow() event

event AddRow(obj Sender, AddRowEventArgs e){
e.beforeRow = 0; (this should be set by the method calling the event but
just in case)
trigger event InsertRow(0)
}

event InsertRow(obj Sender, AddRowEventArgs e){
trigger event PreInsertRow(Sender, e)
if (e.ActionCode = ActionCode.DoNotContinue) then return;

e.newRow = this.InsertRow(e.beforeRow)

// run this event after all other code (descendent etc has finished
processing)
post event PostInsertRow(Sender, e)
}

In my 'PowerBuilder' days, I would simply have created the events with a
return code and checked that. I know the compiler lets me do that but it
didn't seem to clear how to capture that in .Net. Not that I'm all that
sure how to capture the EventArgs either. Do I need to be passing them as
ref? What I have so far is obviously a work in progress. I started using
return values but suddenly I had concerns about what to do when 1) there are
layers of descendants and 2) when other events subscribe.

I'm starting to think is that maybe it is the OnEventFire method that is
really suppose to be doing the logically sorting out of return code /
eventArgs and if it finds one that returns -1 or something it jumps in an
processes it?

public delegate int DWAddRowEventHandler (Object sender, RowActionEventArgs
args);
public delegate int DWPreInsertRowEventHandler (Object sender,
RowActionEventArgs args);
public delegate int DWInsertRowEventHandler (Object sender,
RowActionEventArgs args);
public delegate int DWPostInsertRowEventHandler (Object sender,
RowActionEventArgs args);

public event DWAddRowEventHandler DWAddRow ;
public event DWPreInsertRowEventHandler DWPreInsertRow ;
public event DWInsertRowEventHandler DWInsertRow ;
public event DWPostInsertRowEventHandler DWPostInsertRow ;

protected virtual int DWPreInsertRow(Object sender, RowActionEventArgs
args){return 0;}
protected virtual int DWInsertRow( Object sender, RowActionEventArgs args)
{
int rc;

rc = this.OnDWPreInsertRow(e);
if (rc < 0) return rc;

rc = this.InsertRow( beforeRow );

this.DWPostAddRow(); //************ should this be something like
start a new low priority thread? Seems a touch complicated to do that?

return rc;
}

protected virtual int DWPostInsertRow(Object sender, RowActionEventArgs
args){}

protected virtual int OnDWAddRow( RowActionEventArgs e )
{
if (DWAddRow != null) {
e.beforeRow = 0;
return DWAddRow( this, e);
}
return 0;
}

protected virtual int OnDWPreInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

protected virtual int OnDWInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

protected virtual int OnDWPostInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

Thanks so much for any help. I mostly trying to avoid do a bunch of useless
work because I don't quite understand a couple of concepts.

jack
Nov 16 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
ok, I think I cleared some things up myself but I still have a number of
questions. Please correct me if I am wrong:

1) EventArgs is an object so, everytime its passed around it retains all its
data because its an object, not a int or something.

2) In order to check the progress/results from a chain of delgates (from
inheritence) is to use the GetInvocationList and then manually call them one
at a time and check the return code / EventArgs. This would happen in the
OnXXXEvent method

3) Haven't proven to myself yet but if I wanted the descendent class to
completely override the ancestor event then I need to override the
OnXXXEvent method and somehow ignore the ancestor callbacks? Not sure how
to do this, or is there an easier way? Can I ask a Delete if it is callback
to the current object or an ancestor of the current object? Makes sense in
my mind...

Questions:

A) Is it better to do all the processing based on the EventArgs or use a
return value? Is there a standard or preferred approach?

B) Should I be exposing (ie Public) the Virtual On method so that it can be
called by a button or right mouse click? or should I build an intermediate
layer or something?

C) How to do handle issue 3 above.

thx so much

"Jack Addington" <ja********@shaw.ca> wrote in message
news:%2****************@TK2MSFTNGP10.phx.gbl...
I have a 3rd party object that fires an itemchanged event when someone
edits some data on a form. This event has a custom eventArgs that has a
field called ActionCode. In the code of the event, if you set this
ActionCode to various values the control will respond in various ways
(reject, reject change field, accept, etc). I am trying to understand
exactly how that works as I am trying to extend the control and add more
processing s events. In my previous exposure to languages, the events
simply had return codes and I could intercept them in a descendent or
ancestor and proccess them. Obviously it was hiding the whole idea of
delegates and such.

I could implement all my code as methods but I would like to be able to
put the code on a form, and still be able to extend or override the
framework code.. I've got a few problems understanding the exact
behaviour of the EventArgs (how to return values) and also how to 'post'
and event to fire when there is no more processing to do. Also how does
the eventArgs really work when there are multiple subscribers? If the
first one in the delegate thread fires should the second one be getting
any updates?

This is what I would like to do for letting the user add/insert a new row.
There is a method on the control called InsertRow (int beforeRow){}, 0 =
add to end.

I'm going to define the AddRowEventArgs as (int beforeRow, int actionCode,
int NewRow).

1) User hits button or right mouse to 'Add a new Row'. This calls the
InsertRow() event

event AddRow(obj Sender, AddRowEventArgs e){
e.beforeRow = 0; (this should be set by the method calling the event
but just in case)
trigger event InsertRow(0)
}

event InsertRow(obj Sender, AddRowEventArgs e){
trigger event PreInsertRow(Sender, e)
if (e.ActionCode = ActionCode.DoNotContinue) then return;

e.newRow = this.InsertRow(e.beforeRow)

// run this event after all other code (descendent etc has finished
processing)
post event PostInsertRow(Sender, e)
}

In my 'PowerBuilder' days, I would simply have created the events with a
return code and checked that. I know the compiler lets me do that but it
didn't seem to clear how to capture that in .Net. Not that I'm all that
sure how to capture the EventArgs either. Do I need to be passing them as
ref? What I have so far is obviously a work in progress. I started using
return values but suddenly I had concerns about what to do when 1) there
are layers of descendants and 2) when other events subscribe.

I'm starting to think is that maybe it is the OnEventFire method that is
really suppose to be doing the logically sorting out of return code /
eventArgs and if it finds one that returns -1 or something it jumps in an
processes it?

public delegate int DWAddRowEventHandler (Object sender,
RowActionEventArgs args);
public delegate int DWPreInsertRowEventHandler (Object sender,
RowActionEventArgs args);
public delegate int DWInsertRowEventHandler (Object sender,
RowActionEventArgs args);
public delegate int DWPostInsertRowEventHandler (Object sender,
RowActionEventArgs args);

public event DWAddRowEventHandler DWAddRow ;
public event DWPreInsertRowEventHandler DWPreInsertRow ;
public event DWInsertRowEventHandler DWInsertRow ;
public event DWPostInsertRowEventHandler DWPostInsertRow ;

protected virtual int DWPreInsertRow(Object sender, RowActionEventArgs
args){return 0;}
protected virtual int DWInsertRow( Object sender, RowActionEventArgs
args)
{
int rc;

rc = this.OnDWPreInsertRow(e);
if (rc < 0) return rc;

rc = this.InsertRow( beforeRow );

this.DWPostAddRow(); //************ should this be something like
start a new low priority thread? Seems a touch complicated to do that?

return rc;
}

protected virtual int DWPostInsertRow(Object sender, RowActionEventArgs
args){}

protected virtual int OnDWAddRow( RowActionEventArgs e )
{
if (DWAddRow != null) {
e.beforeRow = 0;
return DWAddRow( this, e);
}
return 0;
}

protected virtual int OnDWPreInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

protected virtual int OnDWInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

protected virtual int OnDWPostInsertRow( RowActionEventArgs e )
{
if (DWAddRow != null) return DWAddRow( this, e);
return 0;
}

Thanks so much for any help. I mostly trying to avoid do a bunch of
useless work because I don't quite understand a couple of concepts.

jack

Nov 16 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.