I know that a lot has been discussed on this thread, and moving the db connection to the Session is what I would do, but was wondering whether the original question could have actually been answered by suggesting to use the page level properties from the ListBox.Shown event rather than ListBox.Open?
The problem with this approach is that you see the listbox content being refreshed which looks horrid and very unprofessional in my opinion. I am a bit a*al about this as I expect a screen to be populated when it is displayed and not flicking as fields change value. It is even more noticeable when you a mobile device. This bug really does need to be addressed in some way other than bodges and hacks.
Why can’t you put all the code in Page.Open?
Yes you could but it would make the code totally unmanageable. The whole point of having the events on controls is to place the code related to that control with the control in its events (sorry I am not trying to teach anyone to suck eggs, just making the point). As an example I have a page that has 3 listboxes that show different things depending on other external things and their is a lot of decision making that goes on before anything is displayed. Then I have lots of other labels that show other information dependent on things. So what I would ideally do is make all the base decisions in the Page.Open and set different properties accordingly and populate dictionaries etc which the controls then use but because I dont know what will fire first this then becomes really difficult as it stands now.
It’s not unprofessional, loading data after UI display is a way of coping with web inherent latency, and also far more responsive feeling to a user than them having to wait for data to be retrieved before seeing UI changes and wondering what’s going on when they press a button and nothing happens for seconds.
Having a snappy and responsive UI is very important to an end user, the feel of relatively immediate response to their action (i.e. button clicked -> new page shown) reduces anxiety and promotes confidence in the application.
With the combination of a Session level db connection, and using the Open and Shown events as intended, you can greatly reduce the perceived time to a full (or visible rows filled if you intelligently page the data) ListBox.
In your example of 3 list boxes and other controls ideally being populated with dictionary data created from analysis, there is nothing to stop you from doing that analysis on Page.Open, storing the data in page level properties and then grabbing what bits of the data you need from each of the control’s Shown events, which are guaranteed to fire after the Page.Open event. This way you spread the work across events and show UI after a hopefully not too long a delay and with data available on the page each of the controls will populate without having to wait for data retrieval.
Maybe my use of “unprofessional” was a little strong but I hate seeing data appearing at different time in different fields on the screen and I appreciate that this is a very subjective thing.
Let me try and give you another example. Lets say I have a page level property called “myDictionary” that I want to store information in before a page is shown. So I Instantiate the property in the pageOpen event and I then use it in the pageOpen to do things. All good so far. For clean coding I go to my listboxOpen event and attempt to access content in the “myDictionary” properties that should have been loaded by the pageOpen event. Now sometimes it will work fine but other times it tells me that the property has not been Instantiated because the pageOpen event has not yet fired.
Which is where the post really started from (in that if you never have a known start point) then where do you Instantiate page level properties. And the answer is that you cant, so you either have to use session properties or you have to Instantiate in the pageOpen and then either put all your code that uses that property in the same event or if you want to keep your code attached to the related control then you have to put it in the controlShown event.
Absolutely, the order of the Open events is effectively undefined, hence we do anything that doesn’t depend on another control to have been instantiated in the Open events, but use the Shown events where control instantiation is required.
If you really want every control to show it’s complete data at the same time, then you could of course hide everything behind a curtain (z-index is your friend here) and then when all the controls have finished their Shown events “drop” the curtain.
[quote=97755:@Rick Araujo]Shouldn’t be the case of introducing a new Event to give the power to a more refined flow control to the users, like:
Event_BeforeOpen() // Pre-actions, before controls creation, like setting some properties
Adding more events doesn’t solve the problem. People will still put things in the wrong place if given the chance. The right thing is for us to fix the framework design flaw that started all of this in the first place, which was that commands could sent to a browser to manipulate a control when the control hadn’t been instantiated yet.
P.S. - Those of you that are in the Beta program should go try this out.
Greg, can I just confirm that when you refer to “control” that also includes windows properties? I also get a little confused when Xojo Gurus refer to controls as my old VB head kicks in and still think of them as just UI things.
Controls = anything that has a web component on the browser… And on the web, that’s usually the UI components.
For instance WebLocation and WebTimer can suffer from this problem, but not a property which is an instance of the Date class. Basically, any of the controls which start with “Web” and are part of the Xojo Web Framework, except for subclasses of WebControlWrapper (unless the developer makes the same mistake we did ).