by Mark Trescowthick - GUI Computing
Drag and Drop is, as the gurus told us it would, becoming ubiquitous. One of its best uses, in my opinion, is to change the order of items in a list - something most users do quite a bit one way or another and, it's my observation, something they'd like to do a lot more of, if only they were allowed.
I, for one, would just love to be able to customise the font listing dropdown in the word processor I'm currently using. I regularly use only perhaps a dozen fonts and having them grouped together would be handy. I know Word will group fonts in a template at the top, but not all the fonts I use are necessarily in a template and, in any event, I'm not using Word right now. So I have no way to do it short of renaming the True Type fonts internally, which is going to cause all sorts of other side effects and probably breaches copyright... but I digress.
Giving a user that sort of functionality is, nowadays, pretty easy using, say, TrueGrid. At least, that is, while the user is dragging within the visible rows of the grid using the DragOver event :
Sub tgTarget_DragOver (Source As Control, X As Single, Y As Single, State As Integer) tgTarget.PointX = X tgTarget.PointY = Y If tgTarget.RowAtPoint > 0 Then tgTarget.RowIndex = tgTarget.RowAtPoint If tgTarget.ColumnAtPoint Then tgTarget.ColumnIndex = tgTarget.ColumnAtPoint End Sub
Of course, I need to also ensure that, when a drop happens, I do what's needed to re-order the grid (which will vary from situation to situation), then do a refresh :
Sub tgTarget_DragDrop (Source As Control, X As Single, Y As Single) ' do whatever reordering you need to tgTarget.Refresh End Sub
But grids have scrollbars and are intended to be scrolled... which the user can't do if they're dragging at the time.
There's a simple solution to this silly but annoying glitch, and that's to put a 'fence' around the grid. I use a couple of ever-so-disposable labels in VB3, but there are obviously different (and better) ways of doing the job depending upon what your development environment is.
Basically, I capture the dragOver event and force a scroll in the appropriate direction within the grid. For example, to scroll our tgTarget grid, I place a label over the top and under the bottom of the grid and simply :
Sub ScrollDownLabel_DragOver (Source As Control, X As Single, Y As Single, State As Integer) If tgTarget.RowIndex < tgTarget.Rows Then tgTarget.RowIndex = tgTarget.RowIndex + 1 End If End Sub Sub ScrollUpLabel_DragOver (Source As Control, X As Single, Y As Single, State As Integer) If tgTarget.RowIndex > 0 Then tgTarget.RowIndex = tgTarget.RowIndex - 1 End If End Sub
If I wanted to get particularly flash / annoying to the user, I could restrict the cursor as well when a drag is in progress. If I did so, I'd probably want to make that an option though - I hate those sort of limitations. I'm also pretty wary of interfering with the cursor in principle - it seems to cause more problems than it solves most of the time.
In any event, this is a handy technique, no matter what language you're using this week. It's also not strictly my idea...