如何分离面板并将其显示在单独的窗口中?
假设我有一个包含面板(其中有许多其他控件)的表单 A 和一个空的表单 B。
我可以通过编程方式将面板与表单 A 分离并将其移动到表单 B 中(也可能返回到表单 A)吗?
我知道我可以更改面板的所有者,但是它可以在不同的表单之间工作吗?
更新:
经过一番谷歌搜索后,我发现有一个 ParentWindow 属性。
Let's say I have form A that contains a panel (with many other controls in it) and a form B that it is empty.
Can I programmatically detach the panel from form A and move it in form B (and maybe back to form A)?
I know that I can change the Owner of the panel but does it work between different forms?
Update:
After some Googling I see that there is a ParentWindow property.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如其他人所指出的,在不更改所有权的情况下更改控件的父窗口存在几个问题,并且如果控件上有多个控件,则更改控件所有者可能会很困难......
解决这个问题的一种方法是使用框架反而。框架拥有它的所有子控件,因此您需要做的就是更改框架的所有者和父级,其他所有内容都会随之而来。这种方法还允许您将所有事件处理程序和粘合代码保留在一个位置。
氮@
As noted by others, there are several problems with changing the parent window of a control without changing the ownership, and changing a controls owner can be difficult if it has multiple controls sitting on it...
One way around it is to use a frame instead. A frame owns all of it's sub-controls, so all you would need to do is change the owner and parent of the frame, and everything else will come along with it. This approach also allows you to keep all the event handlers and glue code in a single place as well.
N@
通过真正使用 TForm 来实现面板的用途,您可以轻松地让某些东西看起来像面板,也可以作为表单。然后在运行时将窗体停靠到为此目的留有空白面板的位置,并以相同的方式在运行时取消停靠它。
您无法取消停靠 TPanel 并将其显示为顶级表单窗口,但您可以获取顶级表单窗口并将其停靠在代码中。要获得您想要的外观和功能,您必须使用正确的工具(在本例中为 TForm)。
顺便说一句,像 Toolbar 2000 这样的组件库确实允许基于工具栏面板的浮动工具栏窗口,因此,如果您确实坚持让所有 designtim 元素在设计时保持一种形式,您应该研究一下它在 Toolbar 2000 中的工作原理。其中有很多代码用于以“取消停靠/浮动”模式呈现工具栏,并处理鼠标驱动的工具栏停靠和从工具栏停靠中取消停靠。
You can easily have something appear as if it was a panel, and also as a form, by really using a TForm for what you would have used the panel for. Then dock the form at runtime into the place where you have a blank panel left for that purpose, and undock it at runtime, by the same manner.
You can't undock a TPanel and have it appear as a top-level form window, but you can take a top level form window and dock it in code. To get the appearance and functionality you want you must use the correct tools (TForm, in this case).
Incidentally, component libraries like Toolbar 2000 do allow floating toolbar windows based on toolbar panels, so if you really insist on having all the designtim elements remain in one form, at desigtime, you should look into how it works in Toolbar 2000. It has a lot of code in there to render the toolbar in "undocked/floating" mode, and to handle the mouse-driven docking and undocking of toolbars into toolbar docks.
您必须考虑所有权,否则表格 A 的破坏将导致表格 B 上的面板消失(即破坏),或更糟。
。
额外的引用可能看起来有点愚蠢:
Form2.InsertedPanel
和Panel1
指向同一个对象,但它在语义上是首选。也许中央控制变量更好。更新:
我错误地认为RemoveComponent级联到面板上的子控件。当然,事实并非如此,因此只有从窗体 A 中删除面板才会使面板的所有子控件仍归窗体 A 所有。因此,我添加了 RemoveComponents 例程以删除面板的所有子控件的所有权。
请注意,此时面板的子控件没有所有者。但由于它们是面板的父控件,因此销毁面板将释放这些控件。因此,请确保该面板有一个父面板,或者显式释放该面板。
以上所有内容仅适用于设计时创建的面板,将设计时放置在表单上,这是我的假设。由于这种改变父母行为显然是想要或需要的,因此您可能需要考虑在运行时完全实现它。为了保持设计面板的能力,我建议创建一个框架,您可以在其上设计该面板,并在表单周围跳转该框架。
You have to take ownership into account, otherwise the destruction of form A would lead to the disappearance (i.e. destruction) of your panel on form B, or worse.
.
The extra reference may seem a bit silly:
Form2.InsertedPanel
andPanel1
point to the same object, but it's kind of semantically preferred. Maybe a central controlled variable is better.Update:
I falsely assumed that RemoveComponent cascaded to the child controls on the panel. It doesn't, of course, so only removing the panel from form A would leave all the child controls of the panel still owned by form A. So I added the RemoveComponents routine to remove ownership from all the child controls of the panel.
Note that the child controls of the panel don't have an owner at this time. But since they are parented controls of the panel, destruction of the panel will free those controls. So be sure the panel has a parent, or free the panel explicitly.
All of the above only applies to a design time created panel, placed design time on the form, which was my assumption. Since this changing parents behaviour is apparently wanted or needed, you might want to consider to implement it completely at runtime. To keep the abbility to design the panel designtime, I suggest to create a Frame on which you can design that panel, and jump the Frame around your forms.
如果面板和子组件是在运行时创建的,则只需将面板的
Parent
设置为FormB
:请注意,
FormB
必须具有在您执行此操作之前已经创建了。有关详细信息,请参阅此处的 Delphi Wiki 页面。
If the panel and child components are created at runtime, you can just set the
Parent
of the Panel toFormB
:Note that
FormB
has to have been created already before you can do this.For more info, see the Delphi Wiki page here.