Home > Archive > C# > January 2006 > Event Raising Strategy
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Event Raising Strategy
|
|
| Diggers 2005-07-28, 9:09 am |
| Hello all,
I'm really not sure if this is the best forum for this question but I
thought I would try here to see if anyone has any insight.
Essentially my problem is to do with an event raising strategy in a
complexish hierarchical object model.
At the top of the tree is Survey. Survey contains a local variable of
type QuestionCollection. This is a strongly typed collection of
Question objects. Question itself is abstract and is genaralized by
TextQuestion and OptionQuestion. An OptionQuestion contains a local
variable of type ResponseCollection which is a strongly type collection
of Response objects. TextQuestion does not.
I am implementing an event model to pass events up the tree when
aspects of the heirarchy change. For example when the contents of a
QuestionCollection changes it sends an event, hence the Survey is able
to know when a question is added removed or changed in its local
variable QuestionCollection.
My problem comes when I want Survey to know about the
ResponseCollection's contents changing. The ResonseCollection can raise
an event to its containing OptionQuestion, but I can't find a way of
then raising an event from this collection to notify the containing
Survey, as Survey has a reference to the abstact QuestionCollection.
I hope this makes sense. Sorry for no code at this stage, but I
literally haven't written any yet as I am still planning this model.
The target language is C# (surprise, surprise).
Some additional info. The reason I want Survey to know about
ResponseCollection changing is that I plan to have a single instance of
Survey in the visual interface and handle events from the model to
update the interface. I am not precious about the class structure and
would welcome any suggestions or alternatives. Just seems to make sense
to me as I will need to iterate through the QuestionCollection
regardless of whether the items within it are Option or Text.
Any comments welcome.
Cheers
Simon Rigby
Inverness, Scotland
| |
| larrylard@hotmail.com 2005-07-28, 5:02 pm |
|
Diggers wrote:
> Hello all,
>
> I'm really not sure if this is the best forum for this question but I
> thought I would try here to see if anyone has any insight.
>
> Essentially my problem is to do with an event raising strategy in a
> complexish hierarchical object model.
>
> At the top of the tree is Survey. Survey contains a local variable of
> type QuestionCollection. This is a strongly typed collection of
> Question objects. Question itself is abstract and is genaralized by
> TextQuestion and OptionQuestion. An OptionQuestion contains a local
> variable of type ResponseCollection which is a strongly type collection
> of Response objects. TextQuestion does not.
>
> I am implementing an event model to pass events up the tree when
> aspects of the heirarchy change. For example when the contents of a
> QuestionCollection changes it sends an event, hence the Survey is able
> to know when a question is added removed or changed in its local
> variable QuestionCollection.
>
> My problem comes when I want Survey to know about the
> ResponseCollection's contents changing. The ResonseCollection can raise
> an event to its containing OptionQuestion, but I can't find a way of
> then raising an event from this collection to notify the containing
> Survey, as Survey has a reference to the abstact QuestionCollection.
How about :
- ResponseCollection has an event ContentsChanged
- Question has an event Changed
- An OptionQuestion listens for its ResponseCollection's
ContentsChanged event, and when it hears that, raises its own Changed
event
- (A TextQuestion never raises its Changed event - at least for the
moment)
- QuestionCollection has an event ContentsChanged
- A QuestionCollection listens for Changed events from *all* its
contained Questions: when a Question is added, a Changed event handler
is hooked up; when a Question is removed, the event handler is
unhooked. When the QuestionCollection hears a Changed event from any of
its contained Questions, it raises its own ContentsChanged event. This
kind of behaviour could loosely be called 'event bubbling', though I
think that term already has a tighter and slightly different meaning
elsewhere. Oh well.
- Survey listens for a ContentsChanged event from its
QuestionCollection, which it will hear (thanks to the 'bubbling'
procedure) whenever the ResponseCollection at the bottom of the object
hierarchy changes.
> I hope this makes sense. Sorry for no code at this stage, but I
> literally haven't written any yet as I am still planning this model.
> The target language is C# (surprise, surprise).
>
> Some additional info. The reason I want Survey to know about
> ResponseCollection changing is that I plan to have a single instance of
> Survey in the visual interface and handle events from the model to
> update the interface.
A vague thought is to just pass a Container to the Survey and tell it
to draw itself in that Container; internally the Survey could create
subcontainers as needed and pass them down to the Questions. Not sure
how viable a strategy this is.
> I am not precious about the class structure and
> would welcome any suggestions or alternatives. Just seems to make sense
> to me as I will need to iterate through the QuestionCollection
> regardless of whether the items within it are Option or Text.
That part looks good. Although you might find yourself wanting to
switch to an IQuestion interface at some point, if the various forms of
question start to diverge in nature.
--
Larry Lard
Replies to group please
| |
| Diggers 2005-07-28, 5:02 pm |
| Nice one Larry,
I wasn't thinking down the line of hooking up the delegates
dynamically.
Like your point about passing the Container to the model for visual
display. I'm going to look at that further but there will eventually be
a web interface to this app as well. I suppose I should give that some
serious thought now.
Yup I think your right about the interface. There are more than likely
going to be other question types later so best to head this off now.
All in all a top class answer. Get yourself a beer (religion
permitting).
Cheers
Simon
| |
| Bruce Wood 2005-07-28, 5:02 pm |
| Larry nailed the solution. Here is the same solution from a different
angle.
For each class in your hierarchy, you want that class to present a
self-consistent, logical public face to any classes that may use it. If
a class contains other objects (by way of aggregation or composition),
then the enclosing class should publish events in _its_ terms.
So, in your example, if QuestionCollection contains Questions, then the
abstract definition for Question should indicate that it can raise a
Changed event. (This doesn't mean that every type of Question can raise
the event... only that a Question has to declare the event and may
raise it.) Your QuestionCollection would then raise a QuestionChanged
event whenever a Question within it changed, passing the changed
Question along as event arguments.
Note the name of the event: QuestionChanged. The QuestionCollection is
exporting an event that is named on QuestionCollection's terms: a
question within the collection has changed (raised its Changed) event.
QuestionCollection itself may have a Changed event, but in terms of the
collection, this means that a Question was added or removed.
The trick is to think of a QuestionCollection in the abstract: what is
this thing, and what can happen to it? It can change, a Question within
it can change, it can be cleared of all Questions, etc. You then define
an interface (or class declaration) that publishes all of this
behaviour.
| |
| toni L 2006-01-10, 10:20 pm |
| quote: Originally posted by Bruce Wood
Larry nailed the solution. Here is the same solution from a different
angle.
For each class in your hierarchy, you want that class to present a
self-consistent, logical public face to any classes that may use it. If
a class contains other objects (by way of aggregation or composition),
then the enclosing class should publish events in _its_ terms.
So, in your example, if QuestionCollection contains Questions, then the
abstract definition for Question should indicate that it can raise a
Changed event. (This doesn't mean that every type of Question can raise
the event... only that a Question has to declare the event and may
raise it.) Your QuestionCollection would then raise a QuestionChanged
event whenever a Question within it changed, passing the changed
Question along as event arguments.
Note the name of the event: QuestionChanged. The QuestionCollection is
exporting an event that is named on QuestionCollection's terms: a
question within the collection has changed (raised its Changed) event.
QuestionCollection itself may have a Changed event, but in terms of the
collection, this means that a Question was added or removed.
The trick is to think of a QuestionCollection in the abstract: what is
this thing, and what can happen to it? It can change, a Question within
it can change, it can be cleared of all Questions, etc. You then define
an interface (or class declaration) that publishes all of this
behaviour.
| |
| toni L 2006-01-10, 10:27 pm |
| quote: Originally posted by toni L
Bruce, did you implement locks on the collection while changing it and how this would work with propagating the events like in your case? |
|
|
|
|