I use in last version of (Xojo 4.1 and before) this sequence :
- in Open event of my canvas, I create a class “c = new myClass” (c is a property with type myClass in the canvas)
- in the Set procedure of all my computed properties, I change some value of the c class (like c.myValue = value).
Now, in 2016r1, c is NIL in all Computed properties : the event open is invoked after (and not before) all first set of computed properties.
It is an issue or a definitive change of comportment of loading object ?
Thanks a lot.
I’d have to see your code to comment
I was under the impression that Computed Propertys all got there setters called when the app started (if global) or when class was first initated (if internal to a class), and THEN the controls on a window… but isn’t the prevailing recommendation “never rely on the order of initialization, as things may change in the future”
@Norman : i put a my sample on http://dl.free.fr/gLR8wl0yW
- the code works well in Xojo 4.1 on my MacBookAir (El capitan last version) but not on 2016r1.
- but doesn’t work on my iMac in 2015R4.1 and 2016r1.
@Dave : your remark is a good one. I can easily change all the code and I’ll do.
ah yeah not disabling my adblocker to download it … sorry
you could mail it to me firstname.lastname@example.org
this is not a bug
The instance on the window has to be created and when this is done all the properties are initialized
That initialization is what you’re seeing call your computed properties
I’m surprised you’re only seeing this now as this has been this way for a very long time (like since before I joined REAL more than 8 years ago)
You can instantiate your class in the Constructor (instead of Open) and it’ll be available when the computed properties get called.
I’ve always found it to be inconsistent. Maybe 16r1 fixes all that!
Not that I know of
Properties on instances placed on a layout will get set up when the layout is instantiated
Basically, and I know you know this, the code is basically as if you had written
dim control as Control
control = new YourControl // so the constructor gets called
control.Property = x
... one for each property
and then eventually the Open event is raised so your control gets a chance to do whatever it needs to in its open event
There are even prior questions about this exact thing here on these forums
The problem is computed properties don’t always get called like they’re supposed to be. I’ve pointed this out several times but it seems much better now.
One situation where it’s still inconsistent is adding a computed property to a class that already has an instance on a window. The new computed properties setter isn’t called when the window opens. Saving and reopening the project will fix this.
Related but this is a different issue where the behaviour for that control / class isn’t updated when the original class is updated
I thought you responded “Not that I know of” to my comment that computed properties on controls are inconsistent and so was giving an example. Maybe I miss read
To Gilles’ issue, wouldn’t moving the “c = new MyClass” code to the Constructor be the ideal solution?
I suppose if thats what you meant by “inconsistent” its related - it wasnt what I understood you to mean.
Whats going on is that the behaviour doesn’t get updated on all instances in a project when you add a property like this.
We would need to push changes to the behaviour out to all instances.
And we’d have to also do all subclass instances and sub-subclasses etc.
Not always as IF he sets properties in the constructor they could get overwritten when the properties are set following the construction
For us the right thing to do is make it so the constructor for a control + setting of properties is basically
dim c as Control
c = new YourCustomControl( all properties here )
so the construction & setting of properties all happens “at once”
Thanks for all exchanges.
Constructor is a good method. I try it with default properties defined and exposed with the inspector behavior.
I modify my code with an internal boolean to be sure that the constructor is called (and not overwritten) and check in the first line of all Set() functions if initialization is ok.
Wouldn’t it be less work (and better coding practice) to test the variable for nil before you access it?