0
votes

While playing with master-detail on relatively heavy tables, I was pleasantly surprised to notice the details section did not refresh immediately during scrolling.

Instead, the refresh only got triggered when I stopped heavily scrolling.

This is as opposed to programmatically execute a SetRange in the After-Scroll event, which was obviously getting triggered at every single scroll.

For simplicity in this question, we can assume that 'custom_operation' is a SetRange, though it need not be limited to this, and could be any other operation.

I've been thinking about how this could be working internally, and the Delphi message queue comes to mind:

I cannot seem to locate the article describing the queue's priority, but it described how messages in the queue have different priority depending on their type (hardware triggers, timer, postmessage..., forgot the order exactly).

Could it be that master-detail internally uses the message queue by posting a message asking for a setrange, but then realize that there are more scroll events happening, thus removing old 'custom' messages and reposting a new one? That way, only when there are no more hardware messages, will the 'custom' message be handled.

Being able to delay the custom_operation until the user stopped doing something would be useful.

How would one go about achieving this? Thanks!

Yes, I know. threads can be also used to make the user-experience smoother, but avoiding the custom_operation in the first place would save unnecessary network traffic.

1
It's more likely that the detail table's refreshing of its display is disabled using DisableControls when the scrolling starts, and then EnableControls is set when the scrolling stops. This stops any data-aware controls attached to the dataset from being updated and most (if not all) of the events associated with the dataset from firing.Ken White
Do you use FireDAC? FireDAC uses TTimer to delay refreshing details data set and data events if enabled (see Navigating M/D, FetchOptions.DetailDelay, DisableDelayedScroll, EnableDelayedScroll).Peter Wolf
@KenWhite from my experience, disabling controls didn't prevent calculated fields events from triggering needlessly. Not sure about other events though.Khorkhe
@PeterWolf no I don't. What you're describing seems to be inline with fpiette's answer belowKhorkhe
What data access library do you use then? You've either set up delayed detail refresh yourself, or it's the default behavior of the library. You should examine and follow library's delayed mechanism to perform further delayed actions on details data set.Peter Wolf

1 Answers

1
votes

I would use a TTimer. I would restart (Stop then start) the timer from the scroll event handler. If the event doesn't come fast enough, the timer will call his OnTimer event handler where you do the operation.

I have done that in a TDelayedEdit component deriving from TEdit. The timer is restarted from the OnChange event. If the user keeps typing, the timer never reach the end but once the user stop typing for as long as the timer interval, then the timer trigger his OnTimer event and my component triggers his OnChange event.