Delphi中的设计时拖放?

7
在Delphi 2006之前(我想是这样),我做了一个类似概念的控件,它与TFlowPanel和TGridPanel还有一些区别。在将我的代码升级到Delphi 2009时,我决定对其进行一些增强。
现在,子控件的顺序由它们的创建顺序确定。FlowPanel和GridPanel使用ControlIndex和其他过滤属性显示了更好的方法,但我想知道是否有办法在设计时处理拖放重新排序?据我所知,将编辑控件拖动并将其放置到我的面板上不会调用我可以访问的任何内容。
我曾经幻想过一种直接检测拖放操作的方法,或者也许检测控件移动的方法,以便我可以确定它应该去哪里。
有什么想法吗?
更新: 好的,我搞定了。容器控件已经重写了AlignControls来管理控件的放置。当您拖动嵌套控件并将其放下时,再次调用AlignControls。然后,我将新坐标与列表中的其他控件进行比较,并将其移动到适当的位置。
我必须解决一些问题(主要与对AlignControls的多次调用有关),但基本概念足够简单。感谢所有评论者的帮助。

"子控件的顺序由它们创建的顺序决定。您想要的是什么顺序?选项卡顺序吗?您想将它们从面板顶部到底部进行选项卡排序吗?" - Serguzest
现在,如果您选择面板,然后向其添加控件,这些控件将按您添加它们的顺序进行布局。要重新排序,您需要剪切和粘贴或查看表单文本并将它们移动。我现在已经添加了一个ControlIndex属性,类似于TFlowPanel,但希望控件的用户能够通过拖放来重新排序。因此,抓住Edit2并将其放到Edit1的左侧,它们就会在面板上神奇地交换位置。 - Cobus Kruger
3个回答

5
不能将已经在表单上的控件拖动并放到您的面板中。拖动仅用于移动控件,而不是更改其父级。要更改父级,请剪切并粘贴。
如果控件已经在您的面板上,并且您想将其移动到面板上的另一个位置,则该面板可以通过覆盖 TWinControl.AlignControls 方法来控制布局。当控件被移动时,它的 SetBounds 方法会被调用,在其中会调用其父窗口上的 AlignControl(Self)。这将调用 AlignControls。请查看 Controls.pas,您会发现它是一个复杂的方法,但它负责控件的布局,而这正是您打算更改的地方。

嗨罗布,我觉得我对于我的容器上放置的控件的意图没有太清楚 - 请看我对约翰评论的回应。关于使用AlignControls来处理重新排序,你当然是对的。我已经在使用AlignControls来排列子控件,但现在我完全忽略了左边和顶部属性。我的担心是考虑这些属性会使确定控件何时仅仅被添加以及用户何时试图重新排序变得相当困难。不过我会试一试并回报结果。 - Cobus Kruger

3
也许以下建议可以帮到您:
您可以在设计器中重新指定控件的父级,而无需进行剪切和粘贴。查看结构窗格,然后将可视控件简单地拖动到结构窗格中另一个父节点上。如果您有一些在流面板中的内容,请将它们全部拖出并按您想要的顺序再次拖回流面板中。
(您可以以这种方式重新指定任何可视控件的父级,而不需要更改除其父级之外的任何内容。我强烈推荐以这种方式进行操作。)
您可以将表单视为文本,并在其中移动声明顺序 - 但显然,在直接编辑“资源”文件时需要小心。
您可以在设计器中设置选项卡顺序,因此您可以基于选项卡顺序制作不同的控件,以使其按您所需的方式工作。您可以右键单击表单并更改非可视控件的创建顺序,但这对可视控件无效。

谢谢,约翰。我的问题实际上与能够在自定义控件中支持它有关 - 基本上是使控件确定另一个控件是否被拖放到形成我的控件边界矩形的位置,以便可以更改其父级。不过我对此有些犹豫 - 除了不知道从哪里开始,它还会使控件的行为与其他容器不同,这可能会使某些使用该控件的用户感到困惑。 - Cobus Kruger
1
你可能想将其作为组件编辑器,然后从右键单击弹出自己的UI,并使用旧式的上下移动或在该控件上实现拖放。 - John Kaster

0
你尝试过为你的网格组件编写一个 "OnDragDrop" 事件吗,在此事件中检查你的组件是否处于设计模式?
我还没有编写这样的组件,但我认为该事件应该会触发。

嗨,LeGEC。我还没有尝试过OnDragDrop,但似乎所有其他鼠标事件都被表单设计器拦截了,因此您永远不会收到有关控件正在被拖动的通知。 - Cobus Kruger
可能与命中测试有关,https://stackoverflow.com/questions/25138204/delphi-vcl-make-element-transparent-to-clicks 和 https://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.Controls.TControl.OnMouseActivate 的评论提供了一些信息(至少适用于窗口控件)。 - George Birbilis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接