We help IT Professionals succeed at work.

Detect which controls are visible to the user

Rabbit80
Rabbit80 asked
on
I have a form that is laid out as in the attached file.

The information in the sub panels is retrieved through web services and is unfortunately quite slow - taking around a minute per 100 results to update fully.

Assume the large panel is called MainPanel and the smaller sub panels are called SubPanel(resultNumber).

The main panel can be scrolled up and down by the user whilst the detail in the sub panels are populating. A user can typically fit around 15 sub panels on the screen at a time.

How can I detect what sub panels are visible to the user after they scroll?

I wish to do this so that I can populate the panels on the screen (ie visible to the user) as a priority.

 
Sub createPanels(byVal results as Array)

Dim NumberOfResults as integer = results.length
Dim SubPanel(NumberOfResults) as Panel

For resultNumber = 0 to NumberOfResults - 1

SubPanel(resultNumber) = new Panel

With SubPanel(resultNumber)
     .BorderStyle = BorderStyle.Fixed3d
     .Dock = DockStyle.Top
     .Height = 60
End With


' Code to add labels etc from results array to the SubPanel
'
' At the moment the call to webservices is in here as well,
' although this is asynchronous and triggers an event when the call is
' complete allowing me to use this data on my SubPanels when it becomes 
' available. I will move these calls to a new sub allowing only 15 requests 
' at a time but I need to know which panels are onscreen in order to 
' prioritise which ones are to be updated next. 

MainPanel.Controls.Add(SubPanel(resultNumber))

' There are several controls that can be clicked on each SubPanel so we add 
' a handler
AddHandler SubPanelItem(resultNumber).Click, AddressOf PanelItemClicked 

Next

End Sub

Open in new window


Form Layout
Comment
Watch Question

Commented:
Easiest way: You can use the top of the controls/panels and see if they are within the window-region by comparing the y-coordinates.
 

Author

Commented:
Won't that be quite inefficient when there are several hundred results? I would have to check every panel every time the user scrolled.
Senior Software Engineer
Commented:
You can calculate the height.

Since, You know the:
1) number of sub-panels.
2) height of one sub-panel
3) Height of Form


number of sub-panel visible = Math.Floor( (Height of sub-panel * number of sub-panels) / Form.Height )

if you are leaving some space over your main panel (as mention in fig)

So, do like this:

 number of sub-panel visible = Math.Floor( (Height of sub-panel * number of  sub-panels) / (Form.Height-(Form.top-MainPanel.Top)) )
Commented:
You can make it more efficient to detect the first and last visible panel. If the user scrolls, you will only have to check those panels to see if the are visible. If you know if the user scrolled up or down, you can even decide which panels to check.
This way, you wil never have to update more than visible and never check more than the ones you were visible plus the ones that have become visible +1 (the last one you check will not be visible).