I would like to keep them locked together. If I scroll to row 35 in one, the other should scroll with it, so that both display the same row. The listboxes always have the same number of items.
I know I can use
MyListBox.ScrollPosition = RowToPlaceAtTop
To scroll either listbox once the position of the other changes, but I’m not sure which events to use to detect movement and get the current top row of the listbox being manipulated.
if row = me.ScrollPosition then
if column = 0 then
// only do this for the top/left displayed cell
otherListBox.ScrollPosition = me.ScrollPosition
end
end
You’ll also want to set up a short period timer for some of the situations. I did this before and got a pretty good result by doing the following:
Making a subclass of listbox for both of the boxes that will be linked
Making a separate controller class that will be notified whenever either listbox is potentially scrolled (via mouseWheel, mouseDown, keyDown) through a method that passes the changed listbox as a parameter and updates the other listbox. It has the properties of MyLeftBox and MyRightBox that can be setup for each instance.
The code for the controller class I used was:
[code]Sub updateScrolling(boxfrom as PlannerBox, timerEnsure as Boolean=true)
dim boxtoupdate as PlannerBox
if boxfrom=nil then
Return
end if
if boxfrom=MyLeftBox then
boxtoupdate=MyRightBox
elseif boxfrom=MyRightBox then
boxtoupdate=MyLeftBox
end if
if boxtoupdate<>nil then
boxtoupdate.UpdatingFromController=true
boxtoupdate.ScrollPosition=boxfrom.ScrollPosition
boxtoupdate.UpdatingFromController=false
end if
if timerEnsure then
MyUpdateTimer= new TimerScrollUpdater
MyUpdateTimer.MyController=me
MyUpdateTimer.myBox=boxfrom
This makes it easier by having all of the scrolling go through one method for either box, and it will also create the timer to ensure that the scrolling is updated in situations when the scrollbar is dragged. The timer will simply call the scroll position function again and prevent the timerEnsure:
Sub Action()
if MyController<>nil and myBox<>nil then
MyController.updateScrolling(myBox,false)
end if
End Sub
Also as a note there were several other functions for syncing between the two, including keeping the listindex the same between them whenever that was changed. So once you set up the controller class you can do a lot more with it than just the scroll position if you need to.
I needed to do several other things with it so I just decided to code whole shebang and include the scroll locking within the controller, but it looks like that way is a lot easier and performs better for the scrolling. Thanks!
It does in Cocoa when I tested it just a few minutes ago. Maybe that’s why I didn’t implement something like that before, as I haven’t visited this code since pre-Cocoa RB, and I’m guessing there might be issues on Windows with it as well.
On Windows, it doesn’t catch the scroll reliably when you grab the thumb with your mouse and scroll. I think I had to resort to a timer way back when I solved this problem. My memory is a little foggy though.
[quote=60561:@Norman Palardy]MouseWheel does
Between 2 lists I think I used 6 lines of code total[/quote]
Right that works fine for mousewheel, keydown, and when clicking around on the scrollbar, but if the user drags the scrollbar they could get out of sync.
if Listbox1.ScrollPosition<>me.ScrollPosition then Listbox1.ScrollPosition=me.ScrollPosition
in the cellBackgroundPaint of each ListBox work? (“Listbox1” being replaced with the other control)
Similar to Tim’s code, but it checks on every paint and only sets when needed…
I can’t seem to find a miss under Cocoa or Win32… I must be missing something…
if Listbox1.ScrollPosition<>me.ScrollPosition then Listbox1.ScrollPosition=me.ScrollPosition
in the cellBackgroundPaint of each ListBox work? (“Listbox1” being replaced with the other control)
Similar to Tim’s code, but it checks on every paint and only sets when needed…
I can’t seem to find a miss under Cocoa or Win32… I must be missing something…[/quote]
Of course !
This is even simpler
Works perfectly here as well
Good call
If have several in-house apps where I have done this sort of thing…
The reason to link vertical scroll position (at least for me) , has been to simulate being able to freeze the leftmost columns of a list while horizontal scrolling… The scroll locking part was easy (though the CellBackgroundPaint workaround did not work in Carbon last time I tried it and I had to use a different approach)
The hard part is to get row highlighting synchronized in all situations without a significant visual lag. The change event fires too late and there are so may ways to highlight rows (and it has to work from either listbox), that it’s hard to write code that does it synchronously.
I know this is a old thread but do y’all have any insight on how you could accomplish this with the WebListbox without the user making a listindex change?