我有一个油漆盒,我希望用户能够移除和移动.所以我将其DragKind设置为dkDock,将其DragMode设置为dmAutomatic,并将其放入DockSite设置为True的面板中.当我将油漆盒移到浮动形状后,我将油漆箱停靠时,我遇到了一种奇怪的行为.浮动窗体的关闭按钮出现在面板内.我附上了两个截图.一个来自原始状态,一个再次对接油漆盒.我错过了什么?
原始状态:
对接后:
UPDATE
使用TLama的解决方案后,结果如下.
解决方法
你没有遗漏任何东西.这就是默认的Dock Manager实现的工作方式.它只是想拥有使用它的Dock站点上可用的关闭按钮.您可以做的是,实现您自己的停靠管理器并覆盖其
AdjustDockRect
方法,该方法控制停靠区域的大小,默认停靠管理器实现在哪里为关闭按钮的抓取器创建了空间.如果你不想要那个抓取器,只需保持dock区域矩形的大小,因为它传递给方法,整个dock站点的大小.换句话说,在该方法覆盖中不执行任何操作.
这是抓取器的功能部分,但除了你需要拦截硬编码的绘图.要做到这一点,你需要覆盖PaintDockFrame
事件方法,就像之前一样,什么都不做.
这是一个代码示例:
type TNoGrabDockManager = class(TDockTree) protected procedure AdjustDockRect(Control: TControl; var ARect: TRect); override; procedure PaintDockFrame(Canvas: TCanvas; Control: TControl; const ARect: TRect); override; end; implementation { TNoGrabDockManager } procedure TNoGrabDockManager.AdjustDockRect(Control: TControl; var ARect: TRect); begin // here you can make space for a grabber by shifting top or left position // of the ARect parameter,which is by default set to the whole dock site // bounds size,so if you do nothing here,there will be no grabber end; procedure TNoGrabDockManager.PaintDockFrame(Canvas: TCanvas; Control: TControl; const ARect: TRect); begin // in this event method,the grabber with that close button are drawn,so // as in case of disabling grabber functionality do precisely nothing for // drawing it here,that will make it visually disappear end;
以下是如何使用此类自定义停靠管理器(有关UseDockManager
属性的说明,请参见下文):
procedure TForm1.FormCreate(Sender: TObject); begin Panel1.DockManager := TNoGrabDockManager.Create(Panel1); Panel1.UseDockManager := True; end;
重要
少数消息来源建议,您应该在设计时将停靠面板的UseDockManager
属性设置为False.我不知道为什么,但是从我做的快速测试中,当我没有在设计时设置该属性时,自定义停靠管理器的一些事件方法没有被触发(即使没有设置,AdjustDockRect
事件方法也能正常工作)这样做,但我个人不会依赖它).