Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design-time drag and drop in Delphi?

Before Delphi 2006 (I think) introduced the TFlowPanel and TGridPanel, I did a control that was similar in concept. It still does a couple of things those controls do not do, and when upgrading my code to Delphi 2009, I decided to add a couple of enhancements to that as well.

Right now, the order of the child controls is determined by their creation order. The FlowPanel and GridPanel show a better way with ControlIndex and other filtered properties, but I was wondering if there is a way to handle drag and drop reordering in design-time? As far as I can tell, dragging an edit control and dropping it onto my panel doesn't call anything that I can access at design-time.

I was half-fantasising about a way to either detect the drop operation directly, or to perhaps detect when a control is moved so I can determine where it should go.

Any ideas?

Update: OK, got it working. The container control was already overriding AlignControls to manage the placement of the controls. When you drag the nested control and drop it, AlignControls is again called. I then compared the new coordinates of the control with the other controls in the list and moved it to the appropriate position.

There were a couple of problems that I had to work through (mostly related to the many calls to AlignControls) but the basic concept is simple enough. Thanks to all the commenters for all the help.

like image 717
Cobus Kruger Avatar asked May 25 '09 07:05

Cobus Kruger


2 Answers

You can't drag a control that's already on the form and drop it onto your panel. Dragging is only for moving a control, not for changing its parent. To change the parent, cut and paste.

If the control is already on your panel, and you want to move it to another position on your panel, then the panel can control the layout by overriding the TWinControl.AlignControls method. When a control is moved, its SetBounds method is called, and among the things tha happens is that it calls AlignControl(Self) on its parent window. That calls AlignControls. Look in Controls.pas, and you'll see that that's a complicated method, but it's what is responsible for the layout of the children on a control, and that's exactly what you're planning to change.

like image 135
Rob Kennedy Avatar answered Nov 09 '22 00:11

Rob Kennedy


Perhaps some of these suggestions might help.

You can re-parent a control in the designer without having to do cut-and-paste. View the structure pane, and simply drag the visual control to the node of another parent in the structure pane. If you have things in a flowpanel, drag everything out of the flow panel and drag them back in the order that you want them to be.

(You can re-parent ANY visual control this way, without changing anything other than its parent. I highly recommend doing it this way.)

You can view the form as text, and move the declaration order around in there -- but obviously you'll need to be careful when editing the "resource" file directly.

You can set tab order in the designer, so you could make a different control based on tab order that works as you want. You can right click on the form and change the creation order of the non-visual controls, but that doesn't work with visual controls.

like image 3
John Kaster Avatar answered Nov 09 '22 01:11

John Kaster