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 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Gambas-user mailing list Gambas-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gambas-user