I have a checkbox in a window with an Action event on it. I want to set the checkbox state programmatically while opening the window. That works fine but the problem is that the Action event triggers (on the checkbox) when I change the checkbox state but the Action event should trigger only if the user changes the checkbox state by mouse or keyboard. I’m confused that the Action event fires while I change the checkbox state programmatically.
Yes, this happens. You need to work around it. Typically I set a boolean called initialising to true, and then test for that in the event handlers and return immediatly if it has value True. Once I am done initialising all these fields I set it to False. In other words, you need to add some logic to cope with this situation.
I often subclass controls and define new events “UserChange”, “ProgramChange”, and “AnyChange”. I differentiate between user-initiated changes and programmatic changes by setting a flag on mousedown, which tells me it’s a user change. Reset the flag on mouseExit, after firing the event, etc.
Thank you all. So confirmed, a workaround is necessary to handle this. So will use one too.Maybe Xojo once is able to differ between user changes and programmatically changes. Obviously there is a need as I’m not the first one discovering this.
This has come up before. I think the point is that there are some circumstances where you’d want an event to fire when a programmatic change is made. And if you don’t want it, it can be worked around.
I would expect it the other way around: By default a programmatic change doesn’t trigger an event but there could be a method on each object type called Trigger that would fire an event on the object like the user would trigger it: my object.trigger(“event_name”) or my_object.event_name.trigger(). That way the developer has the full control and doesn’t have to create additional code (workaround) to handle the situation.
Note that in some situations, OS and user-dependent, a button (or checkbox…) can be clicked with the keyboard, which sounds like it might escape your logic.
I handled this in a similar but different way. basically, my code assumes that any change is caused by the user, unles we know different, and so to set a value w/o triggering the changed event, I subclass all controls and add specific functions to change the value programmatically (with a flag to indicate trigger or not trigger event)
Might be nice to have a parameter that specifies the source of the change. Can easily be subclassed as @Julia_Truchsess mentioned, but I’m a big fan of having more functionality in the framework. That being said, it’s probably never gonna happen unless you do it yourself.
In certain, more complex situations, I will have an integer that keeps track of the state of things. For example, if an update may also trigger another update, you can get into a situation where a Boolean will not be enough. Instead:
if updateUnderway>0 then
'don't do this when an update is happening
end
Using this method, multiple blocks of code wrapped in updateUnderway+/-1 will guarantee that updates only happen when appropriate. If you only use a Boolean, you’ll run into trouble once your code gets complicated enough that it triggers updates in multiple locations.
This “don’t raise events when changed programmatically” was done to a single control in Web 2.0 which broke my projects. I’m also aware of at least one other person with a sizable project that this change in behavior caused a problem for. (It has since been corrected.)