Drag/Drop to move listbox items

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW

Search DelphiForFun.org

As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.


Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 


We receive a few cents from each purchase.  Thanks


Support DFF - Donate

 If you benefit from the website,  in terms of knowledge, entertainment value, or something otherwise useful, consider making a donation via PayPal  to help defray the costs.  (No PayPal account necessary to donate via credit card.)  Transaction is secure.

Mensa Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa 365 Puzzlers  Calendar 2017

Mensa 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)


Feedback:  Send an e-mail with your comments about this program (or anything else).

Search DelphiForFun.org only




I  decided to improve the way that items in the Parts and Supply list items could be rearranged in our Cutlist program and the logical way seemed to be the "drag and drop" method I have seen elsewhere.   This is posting represents the results of my investigation into the techniques for doing that. 

There are three versions included in the source zip file which can be downloaded from the bottom of this page:

ArrangeListbox1 uses Delphi's built-in drag/drop facility.  Three event exits in Listbox1  are used  with the DragType property set to dmAutomatic on a TListbox control. Not counting comments, there are just 12 lines of user written code in this simplest version.   

bullet OnDragStart is called when dragging  is started.  All we need to do here is save the index of the item clicked (which will be pointed to by the ItemIndex property.  I called mine DraggedIndex).  
bulletSince we are dragging and dropping on the same list box, we need to use the OnDragOver event exit to set parameter Accept to True.  
bulletAnd finally, when the user releases the left button, the OnDragEnd event is called passes the X and Y coordinates of the cursor.  The TListbox method ItemAtPoint will convert this to an index of the current item, call it DropIndex.  The TListbox Move method then can be called to move the DraggedIndex item to the DropIndex location.  Move will automatically shift the items toward the dragged item location being evacuated.

There are two things I didn't like about the first version.  I doesn't give much indication where the item would be dropped except the tip of the drag cursor arrow.  Some programs, which I can't identify right now, draw a bold horizontal line where the item will be dropped.  I liked that idea.   Also, if the listbox contains more items than can be displayed on a single page, the only way to drag further is to drop the item at one end of the display area, scroll  up or down, and continue the drag.  I wanted some sort of "auto-scroll" to occur when I moved the cursor above or below the listbox border and there are un-displayed items in that direction.

ArrangeListBox2 addresses the first of those features, giving visual indication of where the item would be dropped.     A new TListbox OnDrawItem event exit contains the code to draw the item text and a horizontal line above or below the text  (above if the text if the dragged item is below this drop point, and below if the dragged item is above the drop point).    The OnDragOver exit takes over the job of forcing the redraw of the items that need to be redrawn.  Here's how that works - ListBoxDragOver calls the Tlistbox ItemFromPoint method to convert the X, Y coordinates to the index of the item that is being dragged over.  It then calls  ListBoxDrawItem for the previous drop index to erase the bold line and then calls it again for the new drop index item to draw the bold line at the new location.   

The third version, ArrangeListBox3, addresses the scrolling problem.  I decided that it was not feasible to solve using the standard drag operations so I replaced OnDragStart, OnDragOver, and OnDragDrop drag event exits  with OnMouseDown, OnMouseMove, and OnMouseUp mouse event exits.  

bulletWith these events, OnMouseDown can set a flag (Draggedflag) saying that dragging is taking place and it can call Mouse.SetCapture to "capture" the mouse and cause all the mouse movement and the button up operations to notify our exit routines even if the mouse leaves the listbox boundaries.  
bulletWhen the mouse is within the boundaries, the mouse exits work just like their drag counterparts.  When the OnMouseMove exit finds that Draggedflag is true, the mouse is above or below the listbox, and the listbox could be scrolled in that direction, then it enables a new timer control (ScrollList)  which pops every 1/4 second to scroll one listbox item in the appropriate direction.  This continues until there are no more items to scroll or the mouse moves back within the listbox boundaries, or the mouse button is released.
bulletOnMouseUp exit just has move to the item if the mouse points to an item, reset  Draggedflag and disable the ScrollList timer. 

Addendum August 8, 2007:  At a viewer's request, I added a "block move" option to the ArrangeListBox4 program  (Version 4) today which allows a contiguous block of selected items to be moved in a single drag operation.    There seems to be a conflict when the ExtendedSelect property is true and a left drag operation is started.  So, for now, block drags are implemented as "right button" drag operations.    

Source code for all three versions is included in the downloadable zip file ArrangeListBoxSource.zip   

Created: June 4, 2007

Modified: May 12, 2018




  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2018, Gary Darby    All rights reserved.