[Gambas-user] Help with Observer 'Stop Event'

Benoît Minisini gambas at ...1...
Mon Mar 27 22:55:11 CEST 2017


Le 27/03/2017 à 22:18, Tobias Boege a écrit :
> On Mon, 27 Mar 2017, Riccardo wrote:
>> I have an observer on a ValueBox control to prevent it changing to zero and
>> to prevent it becoming larger than the value in a different ValueBox.
>>
>> Public Sub valNumObserver_change()
>>
>>   If valNum.value = 0 Then valNum.Value = 1
>>   If valNum.Value > valDen.Value Then Stop Event
>>
>> End
>>
>> With first case, where the zero value is changed to one, works. But the Stop
>> Event doesn't do what I expect (it does nothing actually) in the second
>> line...
>>
>
> The documentation about Stop Event [1] says:
>
>   This statement must be used in an event handler. It tells the interpreter
>   that the event that called the event handler must be cancelled.
>
> This may have mislead you to overestimate what the interpreter does when
> it encounters a Stop Event.
>
> What roughly happens when an object raises an event, by using the Raise
> keyword, is: (1) all "before" observers receive the event, then (2) the
> default observer of the object receives the event, and lastly (3) all
> "after" observers receive the event. For each observer, the corresponding
> event handler is called and as soon as one of these event handlers use
> Stop Event, this whole chain is aborted.
>
> But that's about all the interpreter can do. It stops propagation of the
> event to later observers. Imagine that your Observer object is one of
> potentially many observers waiting in line to be notified of the ValueBox
> Change event. By using Stop Event you tell the interpreter to skip those
> observers behind you, which have not seen the event yet.
>
> At that point, the program flow gets back to the ValueBox -- but the
> important fact is, for the component programmer, the one who wrote the
> ValueBox code, obeying Stop Event is completely voluntary. What he does
> is out of the interpreter's reach.
>
> The programmer can choose to get a notification of whether the event was
> aborted by getting the return value of the Raise keyword:
>
>   Dim bCancel As Boolean
>
>   bCancel = Raise Change
>
> This value tells him if someone called Stop Event or not. But he is free
> to ignore that value, or to react to it however he wants. He may even abort
> the event whenever you tell him not to.
>
> Now look at the source code of ValueBox (comp/src/gb.form/.src/ValueBox.class):
>
> --8<---[ $ grep -C 2 "Raise Change" ValueBox.class ]--------
>   If $hTextBox.Text <> $sLastText Then
>     $sLastText = $hTextBox.Text
>     Raise Change
>   Endif
>
>   --
>   Public Sub DateBox_Change()
>
>     Raise Change
>
>   End
>   --
>   Public Sub CurrencyBox_Change()
>
>     Raise Change
>
>   End
>   --
>   Public Sub IpAddressBox_Change()
>
>     Raise Change
>
>   End
> --8<--------------------------------------------------------
>
> The programmer chose to ignore Stop Event for every instance of raising the
> Change event [*]. I'm not sure if there is anything you can do about it,
> apart from dirty hacks or writing your own ValueBox. Maybe you should just
> try and ask Benoit to add support for Stop Event in the ValueBox.
>
> Regards,
> Tobi
>
> [*] This is normal actually. You can grep through the source tree for
>     "= Raise" on the one hand and "^ *Raise" on the other. It gives me
>     a ratio of 28/865, so about 3% of Raise statements even consider the
>     possibility that the user Stop Event's them. This is only counting
>     non-native Gambas events, though.
>
> [1] http://gambaswiki.org/wiki/lang/stopevent
>

The "Change" event means that something has changed. So there is no 
point in cancelling it, you cannot change the past.

-- 
Benoît Minisini




More information about the User mailing list